(本文参考了《设计模式之禅》一书)
何时应该使用策略模式?
当我们的程序中某些算法需要自由切换时非常适合使用策略模式。
比如我们写一个计算机程序,里面必然有加减乘除等等算法,并且这些算法还应该根据客户点击什么运算符号来自由切换。我们就以加 减算法的实现为例说明如何使用策略模式来优化代码,以及如何优化策略模式。
我们实现计算机的 加 减 算法,最简单的写法应该是这样
算法类
public class Calculator { public final static String ADD = "+"; public final static String SUB = "-"; //算法加 private static int add(int a,int b){ return a + b; } //算法减 private static int sub(int a,int b){ return a - b; } //计算 public static int exe(int a,int b,String exeMethod){ switch (exeMethod) { case ADD: return add(a,b); case SUB: return sub(a,b); default: return 0; } } }
场景类
public class Context { public static void main(String[] args) { int a = Calculator.exe(3, 4, Calculator.ADD); //加法运算 int b = Calculator.exe(3, 4, Calculator.SUB); //减法运算 System.out.println(a+" "+b); } }
现在我们引入策略模式
先定义一个抽象接口
public interface Strategy { int exe(int a,int b); }
再实现加和减算法
//加法 public class CalculatorAdd implements Strategy{ @Override public int exe(int a, int b) { return a + b; } } //减法 public class CalculatorSub implements Strategy{ @Override public int exe(int a, int b) { return a - b; } }
可以看到,我们每个算法都继承了Strategy接口,并且实现的exe()方法。
最后看场景类
public class Context { public static void main(String[] args) { int a = exe(3,4,new CalculatorAdd()); int b = exe(3,4,new CalculatorSub()); System.out.println(a+" "+b); } public static int exe(int a,int b,Strategy strategy){ return strategy.exe(a, b); } }
场景类中的 exe()方法通过传入不同的 Straregy 实现类来完成算法的切换。
我们可以看到,使用了策略模式之后,代码量以及类的数目都比之前多了一些,那么为什么还要使用策略模式呢?策略模式的一个好处是规范了我们的代码。比如我们想要新增一个乘法,那么必须要实现 Strategy 接口,然后实现 exe()方法来编写实际的算法。
虽说如此,但策略模式的问题仍然不少,比如类的数量过多。还有一个致命的缺点就是所有的策略类都必须对外暴露,不然我们就没办法知道有哪些策略类可用,但是这样又违背了迪米特法则,故我们还需要对策略模式进行一些优化,可以将策略模式和别的模式结合使用,来解决上述问题。
我们可以使用策略枚举方法,算法枚举类实现如下:
public enum Calculator { ADD{ @Override public int exe(int a, int b) { return a + b; } }, SUB{ @Override public int exe(int a, int b) { return a - b; } }; public abstract int exe(int a, int b); }
该枚举类中有一个exe()抽象方法,枚举类中的每个成员都要实现该方法来实现具体的算法。
然后在场景类中我们就可以这样使用
public class Context { public static void main(String[] args) { int a = Calculator.ADD.exe(3, 4); //加法运算 int b = Calculator.SUB.exe(3, 4); //减法运算 System.out.println(a+" "+b); } }
可以看到,代码比之前简化了许多,而且可读性高,同时解决的类数目多以及类必须对外暴露等问题。所有说策略枚举方法是一个非常高效有用的方法。
时间: 2024-10-18 12:36:21