欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

设计模式:模板方法模式

程序员文章站 2022-03-27 07:58:34
...

定义

模板方法模式 定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤

Template Method Pattern Define the skeleton of an algorithm in a operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.

 

优缺点

优点:

  1. 封装不变部分,扩展可变部分
  2. 提取公共部分代码,便于维护
  3. 行为由父类控制,子类实现

缺点:

按照一般设计习惯,抽象类负责声明最抽象、最一般的事物属性和方法,实现类完成具体的事物属性和方法。但模板方法模式却颠倒了,抽象类定义了部分抽象方法,由子类实现,子类执行结构影响父类结果,也就是子类对父类产生了影响,增加代码阅读的难度

 

使用场景

  1. 多个子类有公有方法,并且逻辑基本相同
  2. 重要复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能由各个子类实现
  3. 重构时,把相同的代码抽取到父类中,通过钩子函数约束其行为

实现方法

将父类定义为抽象类,叫做抽象模板,在其中定义方法,方法分为2种:

基本方法:由子类实现,并在模板方法中被调用

模板方法:一个或几个,一般是一个具体方法,也就是一个框架,实现对基本方法的调度,完成固定的逻辑

 

具体实现

抽象模板

public abstract class HummerModel {
 
    //基本方法
    protected abstract void start();
 
    protected abstract void stop();
 
    protected abstract void alarm();
 
    protected abstract void engineBoom();
 
    //模板方法,一般都加上final关键字,不允许覆写,防止恶意操作
    final public void run() {
        this.start();
        this.engineBoom();
        if (this.isAlarm()) {
            this.alarm();
        }
        this.stop();
    }
 
    //钩子方法
    protected boolean isAlarm() {
        return true;
    }
}

子类1 覆写父类的钩子方法,反向控制父类运行结果

public class HummerH1Model extends HummerModel {
 
    boolean alarmFlag = true;
 
    @Override
    protected void start() {
        System.out.println("H1 start!");
    }
 
    @Override
    protected void stop() {
        System.out.println("H1 stop!");
    }
 
    @Override
    protected void alarm() {
        System.out.println("H1 alarm!");
    }
 
    @Override
    protected void engineBoom() {
        System.out.println("H1 engineBoom!");
    }
 
    @Override
    protected boolean isAlarm() {
        return this.alarmFlag;
    }
 
    public void setAlarm(boolean isAlarm) {
        this.alarmFlag = isAlarm;
    }
}

子类2:覆写父类钩子方法,指定父类运行结果

public class HummerH2Model extends HummerModel {
 
    @Override
    protected void start() {
        System.out.println("H2 start!");
    }
 
    @Override
    protected void stop() {
        System.out.println("H2 stop!");
    }
 
    @Override
    protected void alarm() {
        System.out.println("H2 alarm!");
    }
 
    @Override
    protected void engineBoom() {
        System.out.println("H2 engineBoom!");
    }
 
    @Override
    protected boolean isAlarm() {
        return false;
    }
}

子类3:不覆写钩子方法,保持父类的运行结果

public class HummerH3Model extends HummerModel {
 
    @Override
    protected void start() {
        System.out.println("H3 start!");
    }
 
    @Override
    protected void stop() {
        System.out.println("H3 stop!");
    }
 
    @Override
    protected void alarm() {
        System.out.println("H3 alarm!");
    }
 
    @Override
    protected void engineBoom() {
        System.out.println("H3 engineBoom!");
    }
}

场景类

public class CLient {
 
    public static void main(String[] args) {
        HummerH1Model h1 = new HummerH1Model();
//        h1.setAlarm(true);
        h1.setAlarm(false);
        h1.run();
        HummerH2Model h2 = new HummerH2Model();
        h2.run();
        HummerH3Model h3 = new HummerH3Model();
        h3.run();
    }
}

参考内容:

《设计模式之禅》秦小波