首页 > 代码库 > Java设计模式--模板方法模式

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

  定义:

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

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

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

模式中的角色技术分享

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

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

示例:模拟程序员的日常

抽象模板

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类型,指明主要的逻辑功能在子类中不能被重写。
  • 钩子方法:由抽象类声明并加以实现。但是子类可以去扩展,子类可以通过扩展钩子方法来影响模版方法的逻辑。
  • 抽象类的任务是搭建逻辑的框架,通常由经验丰富的人员编写,因为抽象类的好坏直接决定了程序是否稳定性。

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

 

优点

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

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

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

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

 

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