模板方法模式
模板方法模式
模板方法顾名思义就是需要定义一个模板,这个模板定义了方法,但是并没有具体实现。需要子类去编写方法的具体实现。这么讲有些晦涩,下面我们通过一个示例来讲解。
制造一辆汽车一般分为以下几步: 第一步:安装汽车引擎 第二步:安装汽车框架 第三步:安装车标。 请你实现一个需求:生成一辆奥迪车和一辆奔驰车。
接到上述需求之后,很容易的写出如下2套代码,分别生成奥迪车和奔驰车。
// 生成奔驰车 public void buildBenz() { buildBenzEngine(); buildBenzFrame(); buildBenzLogo(); } private void buildBenzEngine() { System.out.println("安装奔驰车引擎"); } private void buildBenzFrame() { System.out.println("安装奔驰车框架"); } private void buildBenzLogo() { System.out.println("安装奔驰车车标"); } // 生成奥迪车 public void buildAudi() { buildAudiEngine(); buildAudiFrame(); buildAudiLogo(); } private void buildAudiEngine() { System.out.println("安装奥迪车引擎"); } private void buildAudiFrame() { System.out.println("安装奥迪车框架"); } private void buildAudiLogo() { System.out.println("安装奥迪车车标"); }
上面的代码看着没有什么问题,如果以后再生成宝马车,可以再这样来一遍。那如果以后我想先安装车标,再安装框架怎么办呢?是不是每一个类都需要改动一下 生产车的流程呢?
聪明的你应该已经发现了,我们无论是构建哪种车型,其实流程已经定了。就是安装汽车引擎、安装汽车框架、安装汽车车标。所以我们可以将这些操作方法做成一个流程模板,所有的流程编排都在这个模板里面,而具体的方法实现则交由不同的车型处理。这样不管怎么编排,只要修改模板就好了。
首先我们先定义生产车的模板:
public abstract class AbstractCarTemplate { public void buildCar() { buildEngine(); buildFrame(); buildLogo(); } protected abstract void buildFrame(); protected abstract void buildEngine(); protected abstract void buildLogo(); }
定义好了模板之后,就可以让具体的车型取实现具体的模板方法了。
// 奔驰车 public class Benz extends AbstractCarTemplate { @Override protected void buildFrame() { System.out.println("安装奔驰车引擎"); } @Override protected void buildEngine() { System.out.println("安装奔驰车框架"); } @Override protected void buildLogo() { System.out.println("安装奔驰车车标"); } } // 奥都车 public class Audi extends AbstractCarTemplate { @Override protected void buildFrame() { System.out.println("安装奥迪车引擎"); } @Override protected void buildEngine() { System.out.println("安装奥迪车框架"); } @Override protected void buildLogo() { System.out.println("安装奥迪车车标"); } }
这样如果再生产宝马车,就直接创建宝马车的类,然后继承 AbstractCarTemplate
,实现具体的模板方法即可。并且以后进行流程重编排的时候,这些汽车子类也无需关心。
这种定义一个模板结构,将具体内容延迟到子类去实现的方法就是模板方法。模板方法也是日常工作中用的比较多的设计模式。
通过以上介绍总结一下模板方法的优缺点:
优点:
- 提高代码复用性。将相同部分的代码放在抽象的父类中
- 提高了拓展性。将不同的代码放入不同的子类中,通过对子类的扩展增加新的行为
缺点:
- 引入了抽象类,每一个不同的实现都需要一个子类来实现,导致类的个数增加,从而增加了系统实现的复杂度