[设计模式] 模板方法

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、重要的、复杂的方法,可以考虑作为模板方法。

猜你喜欢

转载自www.cnblogs.com/zhuangmingnan/p/9471869.html