1、模板模式概述
(定义一个操作中的算法的框架,而将一些步骤延迟到子类中,是的子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤)
理解:模板模式灵活使用Java的继承机制,抽象模板一般由基本方法和模板方法,基本方法定义出口让子类实现,完成扩展功能,而模板方法(共性封装)则是对基本方法的调用,用于完成固定逻辑,一般会加final关键字。
父类建立框架,子类在重写了父类部分的方法后,再调用从父类继承的方法,产生不同的结果。
2、优点
1、封装不变部分(模板方法),扩展可变部分(基本方法)
2、提取公共部分代码,便于维护(模板方法)
3、行为由父类控制,子类实现(父类实现了基本方法,子类可以通过扩展增加相应的功能,符合开闭原则)。
3、应用场景
1、多个子类有公有的方法,并且逻辑基本相同时。
2、重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现
3、重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数约束其行为(控制模板方法的执行结构)。
4、DEMO展示
1、抽象汽车模型
public abstract class HummerModel {
public abstract void start();
public abstract void stop();
public abstract void alarm();
public abstract void engineBoom();
final public void run() {
//先发动汽车
this.start();
//引擎开始轰鸣
this.engineBoom();
//需要响再响
tif(this.isAlarm()) {
this.alarm();
}
//到目的地就停车
this.stop();
}
/**
* 钩子方法,默认喇叭是会响的(各实现类覆写该方法,控制喇叭能否响)
*/
protected boolean isAlarm(){
return true;
}
2、H1型号的车(喇叭可控制)
public class HummerH1Model extends HummerModel {
private boolean alarmFlag = true;
@Override
public void start() {
System.out.println("悍马1发动...");
}
@Override
public void stop() {
System.out.println("悍马1停车...");
}
@Override
public void alarm() {
System.out.println("悍马1鸣笛");
}
@Override
public void engineBoom() {
System.out.println("悍马1的引擎声音是这样的...");
}
@Override
protected boolean isAlarm() {
return this.alarmFlag;
}
/**
* 要不要响由客户决定
* @param isAlarm
*/
public void setAlarm(boolean isAlarm){
this.alarmFlag = isAlarm;
}
3、H1型号的车(喇叭不响)
public class HummerH2Model extends HummerModel {
@Override
public void start() {
System.out.println("悍马2发动...");
}
@Override
public void stop() {
System.out.println("悍马2停车...");
}
@Override
public void alarm() {
System.out.println("悍马2鸣笛");
}
@Override
public void engineBoom() {
System.out.println("悍马2的引擎声音是这样的...");
}
//默认没有喇叭
@Override
protected boolean isAlarm() {
return false;
}
}
4、场景展示,用户选择是否需要喇叭响
public class Client {
public static void main(String[] args) throws IOException {
String needAlarm = "1";
System.out.println("-------------悍马H1型号--------------");
System.out.println("H1型号的悍马是否需要喇叭声响?0--不需要, 1--需要");
String type = (new BufferedReader(new InputStreamReader(System.in))).readLine();
//XX公司需要H1型号的车
HummerH1Model h1 = new HummerH1Model();
if(needAlarm.equals(type)) {
h1.setAlarm(true);
}
//模型演示
h1.run();
System.out.println("-------------悍马H2型号--------------");
HummerH2Model h2 = new HummerH2Model();
h2.run();
}
}
展示结构
-------------悍马H1型号--------------
H1型号的悍马是否需要喇叭声响?0–不需要, 1–需要
0
悍马1发动…
悍马1的引擎声音是这样的…
悍马1停车…
-------------悍马H2型号--------------
悍马2发动…
悍马2的引擎声音是这样的…
悍马2停车…