设计模式模式(三):策略者模式

今天学习策略者模式,策略者模式(StrategyPattern)(或者算法簇),通常用于业务经常发生改变。

参考:https://www.runoob.com/design-pattern/strategy-pattern.html

一个类的行为或算法可以在运行时发生改变,那么这种类型设计模式就是行为型设计模式。

在策略者设计模式,我们创建表示各种策略的对象和一个行为随着策略对象发生改变而改变的context对象,策略对象改变context对象的执行算法。

策略者解决的是在多种算法相似的情况下,使用if....else...ss等所带来的的复杂代码。

解决的思路是,将这些算法的代码封装成一个一个的类,实现统一接口。

使用场景: 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中选择一种。 3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题

优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。

缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。

案例一:计算器

  //计算器接口

   public interface Strategy {

      public int doOperation(int num1,int num2);

  } 

  //实现具体的类

  //加法

  public class OperationADD implements Strategy{

    public int doOperation (int num1,int num2){

      return num1+num2;

    }

  }

  //减法

  public class OperationSubstract implements Strategy{

    public int doOperation(int num1,int num2){

      return num1-num2;

    }

  }

  //乘法

  public class OperationMultiply implements Strategy{

    public int doOperation(int num1,int num2){

      return num1*num2;

    }

  }

  //除法

  public class OperationDivision implements Strategy{

    public int doOperation(int num1,int num2){

      return num1/num2;

    }

   }

  //创建Context类

  public class Context{

    private Strategy strategy;

    public Context(Strategy strategy){

      this.strategy = strategy;

    }

    public int executeStrategy (int num1,int num2){

      return strategy.doOperation(num1,num2);  

    }  

  }  

  //Demo

  public class StrategyPatternDemo {
    public static void main(String[] args) {
        Context context = new Context(new OperationAdd());
        System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
         context = new Context(new OperationSubstract());
         System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
        context = new Context(new OperationMultiply()); 、
        System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
    }
   }
 
案例二:代金券案例
  商城发放代金券,有50,100,200,500的 ,要那个给你那个,然后将图片发送到D盘
  //代金券接口
  public interface IDexGold{
    double createDexGold();
  }
  //各种面值代金券的实现类Impl
  //50
  public class I50DexGoldImpl implements IDexGold{
    public double createDexGold(){
      InputStream is = null;
      OutputStream os = null;
      try {
                is = new FileInputStream("50元代金券.jpg");
                os = new FileOutputStream("d:/50元代金券.jpg");
                IOUtils.copy(is,os);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
           return 50;
      
    }
  }
  //100 200 500类似 就不写了。。。
  ....
  ....
  ....
 
  //Context类
  public class ContextDemo{
    private IDexGold dexGold;
    public ContextDemo(IDexGold dexGold){
      super();
      this.dexGold = dexGold;  
    }
    public double show(){
      return dexGold.createDexGold();
    }
    
  }
  
  //测试类
  public class ClientTest  {
     public static void main(String[] args){
       ContextDemo demo = new ContextDemo(new I50GexGoldImpl() );
        demo.show();
       }
  }
  
  

这样优点不用修改核心代码

缺点 但是实例化对象一定会暴露出来

posted @ 2019-08-31 14:15  江流石不转  阅读(305)  评论(0编辑  收藏  举报