1、定義
封裝了一個算法的具體步驟,並允許其中的一個或者多個步驟延遲到子類中去實現。模板方法模式可以在不改變算法結構的情況下,重新定義算法中的某些步驟。
2、使用場景
多個子類有公有的方法,並且基本邏輯相似,對於重複的邏輯可以進行抽象封裝成模板方法,不同的子類去實現具體的存在差異的相關邏輯。簡單來說就是在父類中封裝重複的邏輯,存在差異的部分由子類具體實現。
3、UML類圖
4、代碼實現
/**
* 模板模式:封裝算法框架,確定了算法的執行順序,某些特定的算法由特定子類實現
*
* 定義了沖泡飲料的框架
*/
public abstract class AbstractHotDrink {
/**
* 沖泡熱飲
* 封裝沖泡的算法步驟
*/
protected final void prepareDrink() {
boilWater();
brew();
pourIntoCup();
//使算法框架不固定,更加靈活
if (isCondimentHook()) {
addCondiment();
} else {
System.out.println("不加調料");
}
}
protected void boilWater() {
System.out.println("燒水");
}
/**
* 沖泡具體的飲料
*/
protected abstract void brew();
/**
* 倒入杯子理
*/
protected void pourIntoCup() {
System.out.println("倒入杯子");
}
/**
* 加入什麼調料
*/
protected abstract void addCondiment();
/**
* 是否加入調料
*
* @return
*/
protected boolean isCondimentHook() {
return true;
}
}
/**
* 沖泡咖啡
*/
public class CoffeeImpl extends AbstractHotDrink {
@Override
protected void brew() {
System.out.println("咖啡");
}
@Override
protected void addCondiment() {
System.out.println("加牛奶");
}
}
/**
* 沖泡茶
*/
public class TeaImpl extends AbstractHotDrink {
@Override
protected void brew() {
System.out.println("茶");
}
@Override
protected void addCondiment() {
}
@Override
protected boolean isCondimentHook() {
return false;
}
}
5、總結
與策略模式的區別:
1、模板方法模式封裝的算法的執行步驟,策略模式封裝的是不同的算法,算法之間沒有相互關係,可以進行替換。
2、模板方法模式採用的是繼承的方式來實現,策略模式採用的是組合的方式來實現。
優點:封裝重複邏輯,具體邏輯有子類來實現,便於維護。
在具體代碼的時候,也可以將模板方法模式和策略模式合併在一起使用,具體做法就是對於模板方法模式的需要子類實現的抽象方法抽象成接口,實現接口來提供不同的策略。
代碼:https://gitee.com/os2chen/DesignPattern
參考:《Head First Design》、《Android源碼設計模式解析與實戰》