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停車…