模版方法模式

模版方法:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模版方法使得子类可以在不改变算法结构的情况下,重新定义算法中某些步骤。

例子均来自于设计模式之禅
public abstract class HummerModel {

    // 发动
    public abstract void start();
    
    // 停车
    public abstract void stop();
    
    // 鸣笛
    public abstract void alarm();
    
    // 引擎
    public abstract void engineBoom();
    
    // 开车
    public abstract void run();

}

public class HummerH1Model extends HummerModel {

    public void alarm() {
        System.out.println("悍马H1鸣笛...");
    }
    
    public void engineBoom() {
        System.out.println("悍马H1引擎声音是这样的..."
    }
    
    public void start() {
        System.out.println("悍马H1发动...");
    }
    
    public void stop() {
        System.out.println("悍马H1停车...");
    }
    
    public void run(){
        this.start();
        this.engineBoom();
        this.alarm();
        this.stop();
    }
}

public class HummerH1Model extends HummerModel {

    public void alarm() {
        System.out.println("悍马H2鸣笛...");
    }
    
    public void engineBoom() {
        System.out.println("悍马H2引擎声音是这样的..."
    }
    
    public void start() {
        System.out.println("悍马H2发动...");
    }
    
    public void stop() {
        System.out.println("悍马H2停车...");
    }
    
    public void run(){
        this.start();
        this.engineBoom();
        this.alarm();
        this.stop();
    }
}

到这里我们发现有一部分代码是重复的,这显然不是我们想要的结果

改进
public abstract class HummerModel {

    // 发动
    public abstract void start();
    
    // 停车
    public abstract void stop();
    
    // 鸣笛
    public abstract void alarm();
    
    // 引擎
    public abstract void engineBoom();
    
    // 开车,改为实现方法
    public void run(){
        this.start();
        this.engineBoom();
        this.alarm();
        this.stop();
    }

}

public class HummerH1Model extends HummerModel {

    public void alarm() {
        System.out.println("悍马H1鸣笛...");
    }
    
    public void engineBoom() {
        System.out.println("悍马H1引擎声音是这样的..."
    }
    
    public void start() {
        System.out.println("悍马H1发动...");
    }
    
    public void stop() {
        System.out.println("悍马H1停车...");
    }
    
}

public class HummerH1Model extends HummerModel {

    public void alarm() {
        System.out.println("悍马H2鸣笛...");
    }
    
    public void engineBoom() {
        System.out.println("悍马H2引擎声音是这样的..."
    }
    
    public void start() {
        System.out.println("悍马H2发动...");
    }
    
    public void stop() {
        System.out.println("悍马H2停车...");
    }
    
}

public class Client {
    public static void main(String[] args) {
        HummerModel h1 = new HummerH1Model();
        h1.run();
    }
}
悍马H1发动...
悍马H1引擎声音是这样的...
悍马H1鸣笛...
悍马H1停车...

至此模版模式完成

注意

抽象模板中的基本方法尽量设计为protected类型

优点

  • 封装不变部分,扩展可变部分

把认为是不变部分的算法封装到父类实现,而可变部分的则可以通过继承来继续扩展

  • 提取公共部分代码,便于维护
  • 行为由父类控制,子类实现

使用场景

  • 多个子类有公有的方法,并且逻辑基本相同时。
  • 重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功则由各个子类实现。
  • 重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数(见扩展)约束其行为。

拓展

如果我想让一个车不鸣笛怎么办

public abstract class HummerModel {

    // 发动
    protected abstract void start();
    
    // 停车
    protected abstract void stop();
    
    // 鸣笛
    protected abstract void alarm();
    
    // 引擎
    protected abstract void engineBoom();
    
    //钩子方法,默认喇叭是会响的
    protected boolean isAlarm(){
        return true;
    }
    
    // 开车,改为实现方法
    public void run(){
        this.start();
        this.engineBoom();
        if(this.isAlarm()) {
            this.alarm();
        }
        this.stop();
    }

}

public class HummerH1Model extends HummerModel {

    protected void alarm() {
        System.out.println("悍马H1鸣笛...");
    }
    
    protected void engineBoom() {
        System.out.println("悍马H1引擎声音是这样的..."
    }
    
    protected void start() {
        System.out.println("悍马H1发动...");
    }
    
    protected void stop() {
        System.out.println("悍马H1停车...");
    }
    
    protected boolean isAlarm() {
        return true;
    }
    
}

public class HummerH1Model extends HummerModel {

    protected void alarm() {
        System.out.println("悍马H2鸣笛...");
    }
    
    protected void engineBoom() {
        System.out.println("悍马H2引擎声音是这样的..."
    }
    
    protected void start() {
        System.out.println("悍马H2发动...");
    }
    
    protected void stop() {
        System.out.println("悍马H2停车...");
    }
    
    protected boolean isAlarm() {
        return true;
    }
    
}

public class Client {
    public static void main(String[] args) {
        HummerModel h1 = new HummerH1Model();
        h1.run();
        
        HummerModel h2 = new HummerH2Model();
        h2.run();
    }
}

学习之余也不要忘了劳逸结合哦

喜欢天马行空的同学请关注公众号:

模版方法模式