博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[设计模式] 模板方法
阅读量:6484 次
发布时间:2019-06-23

本文共 2014 字,大约阅读时间需要 6 分钟。

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

转载于:https://www.cnblogs.com/zhuangmingnan/p/9471869.html

你可能感兴趣的文章
<转>SQL Server返回最后一个标识值的三个函数:IDENT_CURRENT、@@IDENTITY、SCOPE_IDENTITY...
查看>>
文件与文件系统的压缩与打包命令
查看>>
mysql命令
查看>>
MySQL通配符与正则表达式
查看>>
linux下修改tomcat内存大小
查看>>
windows下安装redis(转载)
查看>>
php不常用而又实用的函数
查看>>
Html5 Egret游戏开发 成语大挑战(六)游戏界面构建和设计
查看>>
bzoj 1208: [HNOI2004]宠物收养所
查看>>
3cDEOAMONR软件的简单实用(tftp32)
查看>>
Kickstart+Dhcp+Nfs+Tftp+Pxe 最实用的批量linux服务器安装
查看>>
手机端服务器开发Spring MVC上传头像,并返回JSON数据
查看>>
Win7共享/添加打印机
查看>>
它山之石
查看>>
Postfix邮件网关投递邮件报“fatal: open database /etc/postfix/transport.db: No su
查看>>
如何删除彻底归档日志文件
查看>>
虚拟化网络必须开放
查看>>
交换机安全 802.1X、port-security、DHCP SNOOP、DAI、VACL、SPAN RSPAN
查看>>
vue数据监控$set和$delete
查看>>
WSS 3.0部署备忘 二
查看>>