zoukankan      html  css  js  c++  java
  • [设计模式] 模板方法

    1. 定义

      模板方法是在一个方法中定义一个流程/算法的骨架,而其中某些步骤交由子类提供实现。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中某些操作的具体实现。

    2. 应用场景

      当多个对象的行为基本一致,每个对象都维护自己的一整套逻辑,对象之间又有完全相同的某些步骤代码,而逻辑又基本一致,这样让代码比较臃肿。我们在设计中遇到在几个类中遇到相同的流程逻辑,但是具体的计算方式不一致,可以考虑引入模板方法。

    3. 类图

      如下图所示,具体的方法步骤是由模板父类制定的,暴露给子类指定的方法,使得子类可以重写某些现有方法;某些在父模板中无法决定执行逻辑的方法,设定成为抽象类,要求子类一定需要实现该抽象方法;

      

    4. 具体实现

      在抽象模板类中,为了避免算法步骤遭到修改,特意将 doSomeThing() 设置成final,禁止子类的重写。然后提供某些通用的操作,例如doSomeThingPartA(), doSomeThingPartB(),这两个方法是针对所有的子类都是通用的,所以提取公共代码到父类中,这样也避免了代码的冗余和对修改的不便。而doSomeThingPartC(), doSomeThingPartD() 是抽象的方法,需要特定的子类才知道如何进行操作,父类就知道要做这个事情,但是具体怎么做,是由子类自行决定的。

      在这里引入一个设计原则:“好莱坞原则”,即 不要调用我,我会去调用你;这里可以看出,子类只是负责将实现部分补全,但是具体何时调用,是由 客户 和 父类来决定的。这样统一了程序入口,各个子类的职责变成单纯和统一。

    public abstract  class AbstractTemplate {
      protected AbstractTemplate () { };
    
      /**
       */
      public final void doSomeThing()
      {
        doSomeThingPartA();
        doSomeThingPartB();
        doSomeThingPartC();
        doSomeThingPartD();
      }
    
      public abstract  void doSomeThingPartC();
    
      public abstract void doSomeThingPartD();
    
    
      private void doSomeThingPartA()
      {
        System.out.println("doSomeThingPartA");
      }
    
      private void doSomeThingPartB()
      {
        System.out.println("doSomeThingPartB");
      }
    
    
    }

      这是子类的具体实现,将父类中定义好的方法,重写,完成类的具体逻辑,等待服务的调用。然而不仅仅是抽象的方法,在父类中可以有 “空”逻辑的方法,对子类的重写开放,这叫做 “钩子”, 当子类需要重写该方法时候可以重新编写这一方法的逻辑,对于其他不需要的子类,只是当这个方法不可见看待即可,父类不强制重写,提供了空的实现。  

    public class ConcreteClassA extends AbstractTemplate {
      public ConcreteClassA () { };
    
      public void doSomeThingPartC()
      {
        System.out.println("A doSomeThingPartC");
      }
    
    
      public void doSomeThingPartD()
      {
        System.out.println("A doSomeThingPartD");
      }
    
    
    }

      ConcreteClassB 的 具体代码类似  ConcreteClassA , 此处就不做展示。

    5. jdk中的模板方法

      ThreadPoolExecutor.Worker

    6. 总结

      模板方法相对于一组流程,相对步骤固定且一致,但是某些具体的步骤有差别,通过 模板方法来固定流程,实现、重写的方法来实现某些节点的具体逻辑。

    引自  “菜鸟教程”: http://www.runoob.com/design-pattern/template-pattern.html

    优点: 1、封装不变部分,扩展可变部分。 2、提取公共代码,便于维护。 3、行为由父类控制,子类实现。

    缺点:每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。

    使用场景: 1、有多个子类共有的方法,且逻辑相同。 2、重要的、复杂的方法,可以考虑作为模板方法。

  • 相关阅读:
    ubuntu /etc/rc.local 不执行
    HTML中设置页面内嵌跳转
    JS使用AudioContext播放音乐
    Unity实现摄像机以某个物体为中心旋转
    Unity中实现通过鼠标对物体进行旋转平移缩放
    解决Windows上无法创建以点开头的文件问题
    解决FBX模型导入Unity后没有贴图的问题
    nedb中使用update更新数据的原理
    Electron 渲染进程中解决require is not defined的问题
    Base64转Blob的方式
  • 原文地址:https://www.cnblogs.com/zhuangmingnan/p/9471869.html
Copyright © 2011-2022 走看看