前言:
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
介绍 :
意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
如何使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
关键代码:实现同一个接口。
优点:1、算法可以自由切换。 2、避免多重判断。 3、扩展性好。
缺点:1、策略类会增多。 2、所有策略类对外暴露。
注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。
实现:
我们将创建一个定义活动的 Strategy 接口和实现了 Strategy 接口的实体策略类。Context 是一个使用了某种策略的类。StrategyPatternDemo,我们的演示类使用 Context 和策略对象来演示 Context 在它所配置或使用的策略改变时的行为变化。
抽象类:
1 /** 2 * 抽象类 3 */ 4 public interface Strategy { 5 void doOperation(int num1, int num2); 6 }
具体实现类:
1 /** 2 * 加法运算实现类 3 */ 4 @Service 5 public class OperationAdd implements Strategy{ 6 @Override 7 public void doOperation(int num1, int num2) { 8 System.out.println("相加等于" + (num1 + num2)); 9 } 10 } 11 12 13 /** 14 * 乘法运算实现类 15 */ 16 @Service 17 public class OperationMultiply implements Strategy{ 18 @Override 19 public void doOperation(int num1, int num2) { 20 System.out.println("相乘等于" + num1 * num2); 21 } 22 } 23 24 25 /** 26 * 减法运算实现类 27 */ 28 @Service 29 public class OperationSubstract implements Strategy{ 30 @Override 31 public void doOperation(int num1, int num2) { 32 System.out.println("相减等于" + (num1 - num2)); 33 } 34 }
策略类:
1 /** 2 * 策略类 3 */ 4 public class Content { 5 private Strategy strategy; 6 public Content(Strategy strategy){ 7 this.strategy = strategy; 8 } 9 10 public void executeStrategy(Integer num1,Integer num2){ 11 strategy.doOperation(num1,num2); 12 } 13 }
启动类:
1 @SpringBootApplication 2 public class StartClass { 3 public static void main(String[] args){ 4 Content content = new Content(new OperationAdd()); 5 content.executeStrategy(6,9); 6 7 Content content1 = new Content(new OperationMultiply()); 8 content1.executeStrategy(6,9); 9 10 Content content2 = new Content(new OperationSubstract()); 11 content2.executeStrategy(6,9); 12 } 13 }
控制台:
总结:
1、策略模式体现了开闭原则:策略模式把一系列的可变算法进行封装,从而定义了良好的程序结构,在出现新的算法的时候,可以很容易的将新的算法实现加入到已有的系统中,而已有的实现不需要修改。
2、策略模式体现了里氏替换原则:策略模式是一个扁平的结构,各个策略实现都是兄弟关系,实现了同一个接口或者继承了同一个抽象类。这样只要使用策略的客户端保持面向抽象编程,就可以动态的切换不同的策略实现以进行替换。