設計模式-模板方法(Template Method)
阿新 • • 發佈:2018-11-24
概述
- 定義 : 定義了一個演算法的骨架, 並允許子類為一個或多個步驟提供實現
- 模板方法使得子類可以在不改變演算法結構的情況下, 重新定義演算法的某些步驟
- 型別 : 行為型
適用場景
- 一次性實現一個演算法的不變的部分, 並將可變的行為留給子類來實現
- 各子類中公共的行為被提取出來並集中到一個公共的父類中, 從而避免程式碼重複
優點
- 提供複用性
- 提高擴充套件性
- 符合開閉原則
缺點
- 類數目增加
- 增加了系統實現的複雜度
- 繼承關係自身缺點, 如果父類新增新的抽象方法, 那麼所有子類都要修改
擴充套件
- 鉤子方法
模式角色
-
AbstractClass(抽象類) :
- 定義抽象的原語操作(primitive operation),具體的子類將重定義它們以實現一個演算法的各步驟。
- 實現一個模板方法,定義一個演算法的骨架。該模板方法不僅呼叫原語操作,也呼叫定義
在AbstractClass或其他物件中的操作。
-
ConcreteClass(具體類) : 實現原語操作以完成演算法中與特定子類相關的步驟
程式碼實現
場景
將一件東西放入冰箱, 需要如下步驟:
- 給冰箱通電(如果需要)
- 開啟冰箱(公共方法)
- 放入東西 -子類重寫選擇放入什麼東西
- 關閉冰箱
程式碼
AbstractClass :
/**
* 抽象類
*
* @author 七夜雪
* @create 2018-11-24 11:02
*/
public abstract class AbstractClass {
public void excute(){
if (isNeedPrepare()) {
prepare();
}
openFridge();
put ();
closeFridge();
}
public void prepare(){
System.out.println("給冰箱通電...");
}
// 鉤子方法, 子類可以通過重寫這個方法控制prepare方法是否執行
public boolean isNeedPrepare(){
return false;
}
public void openFridge(){
System.out.println("開啟冰箱...");
}
public abstract void put();
public void closeFridge(){
System.out.println("關閉冰箱...");
}
}
ConcreteClass1, 重寫了鉤子方法 :
/**
* 子類1 : 將大象放入冰箱
*
* @author 七夜雪
* @create 2018-11-24 11:08
*/
public class ConcreteClass1 extends AbstractClass {
@Override
public void put() {
System.out.println("將大象放入冰箱...");
}
@Override
public boolean isNeedPrepare() {
return true;
}
}
ConcreteClass2 :
/**
* 子類2 : 將老虎放入冰箱
*
* @author 七夜雪
* @create 2018-11-24 11:08
*/
public class ConcreteClass2 extends AbstractClass {
@Override
public void put() {
System.out.println("將老虎放入冰箱...");
}
}
測試程式碼 :
/**
* @author 七夜雪
* @create 2018-11-24 11:12
*/
public class Client {
public static void main(String[] args) {
AbstractClass cls1 = new ConcreteClass1();
AbstractClass cls2 = new ConcreteClass2();
cls1.excute();
cls2.excute();
}
}
測試結果:
給冰箱通電...
開啟冰箱...
將大象放入冰箱...
關閉冰箱...
開啟冰箱...
將老虎放入冰箱...
關閉冰箱...
本文參考:
慕課網<java設計模式精講 Debug 方式+記憶體分析>課程
四人幫<設計模式>