xiaobenchi

导航

设计模式之行为型1

设计模式之行为型1

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

1. 策略模式

面向对象的编程并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。

策略模式(Strategy): 它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

封装变化点是我们面向对象的一种很重要的思维方式。

  • 策略模式结构图

    image-20220727090821504

  • 实现方式

    • Strategy类,定义所有支持算法的公共接口

      public  class Strategy{
          //算法方法
          public  void alogorithmInterface();
      }
      
    • ConcreteStrategy,封装了具体的算法或行为,实现Strategy

      //具体算法A
      class ConcreteStrategyA extends Strategy{
          //算法A实现方法
          @override
          public void algorithmInterface(){
              System.out.println("算法A实现");
          }
      }
      
      //具体算法B
      class ConcreteStrategyB extends Strategy{
          //算法B实现方法
          @override
          public void algorithmInterface(){
              System.out.println("算法B实现");
          }
      }
      
      //具体算法C
      class ConcreteStrategyC extends Strategy{
          //算法B实现方法
          @override
          public void algorithmInterface(){
              System.out.println("算法C实现");
          }
      }
      
    • Context,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用。

      //上下文
      class Context{
          Strategy strategy;
          
          //初始化时传入具体的策略对象
          public Context(Strategy strategy){
              this.strategy = strategy;
          }
          
          //上下文接口
          pulic void contextInterface(){
              //根据具体的策略对象,调用其算法的方法
              strategy.algorithmInterface();
          }
      }
      
    • 客户端代码

      static void main(String[] args){
          Context context;
          
          context = new Context(new ConcreteStrategyA());
          context.contextInterface();
          
          context = new Context(new ConcreteStrategyB());
          context.contextInterface();
          
          context = new Context(new ConcreteStrategyC());
          context.contextInterface();
          
      }
      
  • 超市折扣收银系统的策略模式实现

    • 代码结构图

      image-20220727094458158

    • 现金收费抽象类CashSuper

      abstract class CashSuper{
          public abstract double accpetCash(double money);
      }
      
    • 正常收费子类

      class CashNormal extends CashSuper{
      	@override
          public double acceptCash(double money){
              //正常收费,以原价返回
              return money;
          }
      }
      
    • 打折收费类

      class CashRebate extends CashSuper{
          private double moneyRebate = 1d;
          
          public CashRebate(String moneyRebate){
              this.moneyRebate = Double.parseDouble(moneyRebate);
          }
          
          @override
          public double acceptCash(double money){
              return money*moneyRebate;
          }
      }
      
    • CashContext类

      class CashContext{
          private CashSuper cs; //声明一个CashSuper对象
          
          public CashContext(CashSuper csuper){
              this.cs = csuper;
          }
          
          public double GetResult(double money){
              return cs.acceptCash(money);
          }
          
      }
      
    • 客户端主要代码

      double total = 0.0d; //用于总计
      private void btn_Click(Object sender,EventArgs e){
          CashContext cc = null;
          switch(){
                  case "正常收费":
                      cc = new CashContext(new CashNormal());
                  	beak;
                  case "打8折"
               
                      ...
          }
          
      }
      
  • 策略与简单工厂结合

    客户端里面加了分支判断,可以使用简单工厂与其结合

    将实例化具体策略的过程由客户端转移到Context类中。

    image-20220727100525541

2. 模板方法模式

当我们要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理。

模板方法模式,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

  • 模板方法模式结构图

    image-20220727104014527

  • 代码实现

    • AbstractClass抽象类

      abstract class AbstractClass{
          
          //一些抽象行为放到子类去实现
          public abstract void primitiveOperation1();
          public abstract void primitiveOperation1();
          
          //模板方法,给出了逻辑的骨架,而逻辑的组成时一些相应的抽象操作,它们都推迟到子类实现
          public void TemplateMethod(){
          	public abstract void primitiveOperation1();
          	public abstract void primitiveOperation1();
              System.out.println("");
          }
      }
      
    • ConcreteClass,实现父类所定义的一个或多个抽象方法。每一个AbstractClass都可以由任意多个ConcreteClass与之对应。

      class ConcreteClassA extends AbstractClass{
          @override
          public void primitiveOperation1();{
              System.out.println("具体类A方法1实现");
          }
          
          @override
          public void primitiveOperation2();{
              System.out.println("具体类A方法2实现");
          }
      }
      
      class ConcreteClassB extends AbstractClass{
          @override
          public void primitiveOperation1();{
              System.out.println("具体类B方法1实现");
          }
          
          @override
          public void primitiveOperation2();{
              System.out.println("具体类B方法2实现");
          }
      }
      
    • 客户端调用

      static void main(String[] args){
          AbstractClass c;
          
          c = new ConcreteClassA();
          c.TemplateMethod();
          
          c = new ConcreteClassB();
          c.TemplateMethod();
          
      }
      
  • 小结

    当可变的行为和不可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现。我们通过模板方法模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复不变行为的纠缠。

posted on 2022-07-27 11:04  小迟在努力  阅读(19)  评论(0编辑  收藏  举报