Java设计模式--模板方法模式

时间:2023-03-09 15:19:51
Java设计模式--模板方法模式

  定义:

  模板模式是一种行为设计模式,使用了JAVA的继承机制,在抽象类中定义一个模板方法,该方法引用了若干个抽象方法(由子类实现)或具体方法(子类可以覆盖重写)。它的实现思路是,创建一个桩方法,并且定义一些步骤让子类来实现。模板方法定义了一个算法的执行步骤,或者说能够提供一种默认的实现,这种实现概括一部分子类或者全部子类的共同部分。

  举一个例子帮助理解,假设提供一种造房子的算法。算法的步骤就是模拟造房子的过程:建地基、建支撑,最后添加墙和窗户 – 1. Fundation,2. Pillars,3. Walls,4. Windows。最重要的一点就是不能改变此建造过程,比如不可能在没用地基的时候就开始建造窗户。这个例子中,我们就创建了一个模板方法 – 将使用不同的方法完成对房子的建造。

  为了确保子类不能重写(override)这个模板方法,应当使用final

模式中的角色Java设计模式--模板方法模式

抽象模板:定义了一个模板方法和若干抽象方法和具体方法.

具体模板:继承抽象模板类并实现抽象方法.

示例:模拟程序员的日常

抽象模板

package com.pichen.dp.behavioralpattern.templatemethod;

public abstract class Day {

    public void getUp(){
System.out.println("get up~");
}
public abstract void breakfast();
public abstract void goToWork();
public abstract void working();
public abstract void lunch();
public abstract void goHome();
public abstract void supper();
public void sleep(){
System.out.println("sleep~");
}
//模板方法
public final void process(){
getUp();
breakfast();
goToWork();
working();
lunch();
working();
goHome();
supper();
sleep();
}
}

具体模板

package com.pichen.dp.behavioralpattern.templatemethod;

public class ProgrammerDay extends Day{

    /**
* @see com.pichen.dp.behavioralpattern.templatemethod.Day#breakfast()
*/
@Override
public void breakfast() {
System.out.println("breakfast:noodle~"); } /**
* @see com.pichen.dp.behavioralpattern.templatemethod.Day#goToWork()
*/
@Override
public void goToWork() {
System.out.println("goToWork:drive car~"); } /**
* @see com.pichen.dp.behavioralpattern.templatemethod.Day#working()
*/
@Override
public void working() {
System.out.println("working: coding~"); } /**
* @see com.pichen.dp.behavioralpattern.templatemethod.Day#lunch()
*/
@Override
public void lunch() {
System.out.println("lunch: eat rice~"); } /**
* @see com.pichen.dp.behavioralpattern.templatemethod.Day#goHome()
*/
@Override
public void goHome() {
System.out.println("goHome: walk~");
} /**
* @see com.pichen.dp.behavioralpattern.templatemethod.Day#supper()
*/
@Override
public void supper() {
System.out.println("supper: rice~");
} }

客户端

package com.pichen.dp.behavioralpattern.templatemethod;

public class Main {

    public static void main(String[] args) {
Day programmerDay = new ProgrammerDay();
programmerDay.process();
}
}

结果

get up~
breakfast:noodle~
goToWork:drive car~
working: coding~
lunch: eat rice~
working: coding~
goHome: walk~
supper: rice~
sleep~

模版方法模式的结构

模版方法模式由一个抽象类和一个(或一组)实现类通过继承结构组成,抽象类中的方法分为三种:

  • 抽象方法:父类中只声明但不加以实现,而是定义好规范,然后由它的子类去实现。
  • 模版方法:由抽象类声明并加以实现。一般来说,模版方法调用抽象方法来完成主要的逻辑功能,并且,模版方法大多会定义为final类型,指明主要的逻辑功能在子类中不能被重写。
  • 钩子方法:由抽象类声明并加以实现。但是子类可以去扩展,子类可以通过扩展钩子方法来影响模版方法的逻辑。
  • 抽象类的任务是搭建逻辑的框架,通常由经验丰富的人员编写,因为抽象类的好坏直接决定了程序是否稳定性。

实现类用来实现细节。抽象类中的模版方法正是通过实现类扩展的方法来完成业务逻辑。只要实现类中的扩展方法通过了单元测试,在模版方法正确的前提下,整体功能一般不会出现大的错误。

优点

容易扩展。一般来说,抽象类中的模版方法是不易反生改变的部分,而抽象方法是容易反生变化的部分,因此通过增加实现类一般可以很容易实现功能的扩展,符合开闭原则。

便于维护。对于模版方法模式来说,正是由于他们的主要逻辑相同,才使用了模版方法,假如不使用模版方法,任由这些相同的代码散乱的分布在不同的类中,维护起来是非常不方便的。

比较灵活。因为有钩子方法,因此,子类的实现也可以影响父类中主逻辑的运行。但是,在灵活的同时,由于子类影响到了父类,违反了里氏替换原则,也会给程序带来风险。这就对抽象类的设计有了更高的要求。

在多个子类拥有相同的方法,并且这些方法逻辑相同时,可以考虑使用模版方法模式。在程序的主框架相同,细节不同的场合下,也比较适合使用这种模式