策略模式涉及到三个角色:
● 环境(Context)角色:持有一个Strategy的引用。
● 抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
● 具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
场景假设:两个数相加 和 两个数相减
package com.cl.www; /** * 抽象策略(Strategy)角色 * */ public interface CalculatorStrategy { Integer calculate(Integer number1, Integer number2); }
package com.cl.www; /** * 具体策略(ConcreteStrategy)角色 * 加法计算 */ public class AddCalculate implements CalculatorStrategy{ @Override public Integer calculate(Integer number1, Integer number2) { return number1+number2; } }
package com.cl.www; /** * 具体策略(ConcreteStrategy)角色 * 减法计算 */ public class SubtractCalculate implements CalculatorStrategy{ @Override public Integer calculate(Integer number1, Integer number2) { return number1 - number2; } }
package com.cl.www; /** * 环境(Context)角色:持有一个Strategy的引用。 * */ public class Calculator { private CalculatorStrategy calculatorStrategy; public Calculator(CalculatorStrategy calculatorStrategy){ //初始化的时候传入相应的策略。 this.calculatorStrategy = calculatorStrategy; } public Integer executeCalculate(Integer number1, Integer number2){ return this.calculatorStrategy.calculate(number1, number2); //根据相应的策略调用相应的方法。 } }
package com.cl.www; /** * * 客户端 , * */ public class Client { public static void main(String[] args) { //创建需要的策略对象 CalculatorStrategy addStrategy = new AddCalculate(); // 加法策略 CalculatorStrategy subtractStrategy = new SubtractCalculate(); //减法策略 //创建环境角色,该对象需要接收一个 策略对象。 Calculator addCalculator = new Calculator(addStrategy); //传入加法策略 Integer result = addCalculator.executeCalculate(4, 3); //执行相应的加法算法 System.out.println(result); //输出结果为 7 Calculator subCalculator = new Calculator(subtractStrategy); //传入减法策略 Integer result2 = subCalculator.executeCalculate(4, 3); //执行相应的减法算法 System.out.println(result2); //输出结果为 1 /** * 总结: * *从上面的示例可以看出,策略模式仅仅封装算法,提供新的算法插入到已有系统中,以及老算法从系统中“退休”的方法, *策略模式并不决定在何时使用何种算法。在什么情况下使用什么算法是由客户端决定的。 *我们传什么样的策略,执行什么样的方法,策略模式的重心不是如何实现算法,而是如何组织、调用这些算法, *从而让程序结构更灵活,具有更好的维护性和扩展性。 假如这时我们需要计算 “乘法” 和 “除法”, *我们只需要实现CalculatorStrategy接口, *实现相应的算法,然后在客户端调用 *其实细心的小伙伴会发现,我们可能都用过策略模式,TreeSet set = new TreeSet<>(Comparator<T>); *TeeSet 在排序的时候,传入什么样的比较器就按照什么规则排序,我们可以实现Comparator接口实现我们自己的排序规则。 * */ } }