策略模式定义

Define a familly algorithms, encapsulate each one, and make them interchangeable.(定义一组算法,将每个算法都封装起来,并且使他们之间互相转换)。
从以上官方定义分析到策略模式具有三个角色分别是:

  • 封装角色
  • 抽象策略角色(策略接口)
  • 具体策略角色(实现策略接口的类)

    策略模式实现计算器

    我们分析一下计算器的简单运算,以加减法为例来划分一下其中的角色,比如 加法:1+1=2,减法1-1=0。这里加法和减法都是一个运算可以理解为两个策略;他们都有计算的功能需要定义一个接口提供统一的运算方法,这个为抽象策略角色;高层实现减价法则为封装角色及将接口放进去,通过接口调用,所以高层不用知道具体是加法还是减法。
    因此封装角色起到了承上启下的作用,屏蔽了高层模块对策略、算法的直接访问,封装可能存在的变化。
    下来简单实现计算器加减法的功能:
    策略的接口,定义执行的方法: ```
  1. package design.strategy.c001;
  2. /**
    • 定义策略接口(一组策略)
    • @author yanwenfei
  3. *
  4. */
  5. public interface IStrategy {
  6. //策略需要执行的方法
  7. public int exec(int a, int b);
  8. } ```

创建具体的策略角色及加法和减法

  1. 1. package design.strategy.c001;
  2. 2.
  3. 3. /**
  4. 4. * 策略A加法
  5. 5. * @author yanwenfei
  6. 6. *
  7. 7. */
  8. 8. public class StrategyADD implements IStrategy {
  9. 9.
  10. 10. @Override
  11. 11. public int exec(int a, int b) {
  12. 12. return a+b;
  13. 13. }
  14. 14.
  15. 15. }
  1. 1. package design.strategy.c001;
  2. 2.
  3. 3. /**
  4. 4. * 减法策略
  5. 5. * @author yanwenfei
  6. 6. *
  7. 7. */
  8. 8. public class StrategySub implements IStrategy {
  9. 9.
  10. 10. @Override
  11. 11. public int exec(int a, int b) {
  12. 12. return a - b;
  13. 13. }
  14. 14.
  15. 15. }

封装角色。这里通过构造方法将具体的策略传入高层,而高层不用知道具体是哪种策略,只需要调用抽象策略的方法即可

  1. 1. package design.strategy.c001;
  2. 2.
  3. 3. /**
  4. 4. * 策略分装类
  5. 5. * @author yanwenfei
  6. 6. */
  7. 7. public class Calculator {
  8. 8.
  9. 9. private IStrategy strategy;
  10. 10.
  11. 11. //切换策略
  12. 12. public Calculator(IStrategy strategy) {
  13. 13. this.strategy = strategy;
  14. 14. }
  15. 15.
  16. 16. //执行策略方法
  17. 17. public int exec(int a, int b){
  18. 18. return strategy.exec(a, b);
  19. 19. }
  20. 20. }

场景类

  1. 1. package design.strategy.c001;
  2. 2.
  3. 3. public class TestMain {
  4. 4.
  5. 5. public static void main(String[] args) {
  6. 6.
  7. 7. Calculator calculator = null;
  8. 8.
  9. 9. IStrategy streadd = new StrategyADD();//创建加法策略;
  10. 10. calculator = new Calculator(streadd);//切换策略
  11. 11. int add = calculator.exec(20, 30);
  12. 12. System.out.println("20 + 30 = " + add);
  13. 13.
  14. 14. IStrategy stresub = new StrategySub();//创建减法策略;
  15. 15. calculator = new Calculator(stresub);//切换策略
  16. 16. int sub = calculator.exec(20, 30);
  17. 17. System.out.println("20 - 30 = " + sub);
  18. 18. }
  19. 19.
  20. 20. }

运算结果:

  1. 1. 10 + 30 = 40
  2. 2. 10 - 30 = -20

以上为策略模式传统的实现方式,肯定很多人能看出来这个策略模式有很多缺点,虽然便于扩展,但是每一个策略都是一个类,这个先不说,下来看一下很牛逼的策略枚举。

策略枚举

我们可以使用枚举在一个类中实现以上所有的功能及三种不同的角色,对不熟悉枚举的小伙伴可以查阅资料,下来看看通过枚举实现策略模式

  1. 1. package design.strategy.c002;
  2. 2. /**
  3. 3. * 策略枚举
  4. 4. * @author yanwenfei
  5. 5. */
  6. 6. public enum Calculator {
  7. 7.
  8. 8.
  9. 9.
  10. 10. ADD("+") {
  11. 11. @Override
  12. 12. public int exec(int a, int b) {
  13. 13. // TODO Auto-generated method stub
  14. 14. return a+b;
  15. 15. }
  16. 16. },
  17. 17.
  18. 18. SUB("-") {
  19. 19. @Override
  20. 20. public int exec(int a, int b) {
  21. 21. // TODO Auto-generated method stub
  22. 22. return a-b;
  23. 23. }
  24. 24. };
  25. 25.
  26. 26.
  27. 27. public abstract int exec(int a, int b);
  28. 28.
  29. 29. //运算符
  30. 30. private String value = "";
  31. 31.
  32. 32. private Calculator(String value) {
  33. 33. this.value = value;
  34. 34. }
  35. 35.
  36. 36. public String getValue() {
  37. 37. return value;
  38. 38. }
  39. 39.
  40. 40. }

场景类:

  1. 1. package design.strategy.c002;
  2. 2.
  3. 3. public class TestMain {
  4. 4.
  5. 5. public static void main(String[] args) {
  6. 6.
  7. 7. int add = Calculator.ADD.exec(10, 30);
  8. 8. System.out.println("10 + 30 = "+add);
  9. 9.
  10. 10. int sub = Calculator.SUB.exec(10, 30);
  11. 11. System.out.println("10 - 30 = "+sub);
  12. 12. }
  13. 13. }

运算结果:

  1. 1. 10 + 30 = 40
  2. 2. 10 - 30 = -20

https://blog.csdn.net/fly_air/article/details/52424695