一.模板模式
1. 模板方法模式初探
模板操作模式定義了一個算法中的統一框架,而將一些步驟延遲到子類中實現,使得子類可以在不改變算法結構的同時重新定義算法的某些特定步驟。這就是模板模式。
1. 模板方法模式的代碼實現
1.1 用抽象基類定義框架
/*
* 抽象基類,爲所有子類提供一個算法框架
* 提神飲料
*/
public abstract class RefreshBeverage {
//禁止子類對算法框架做任何的改變.Template模板
/*
* 製備飲料的模板方法
* 封裝了所有子類共同遵循的算法框架
* ctrl+1 可以自動生成方法
*/
public final void prepareBeverageTemplate() {
//1.將水煮沸
boilWater();
//2.泡製飲料
brew();
//3.將飲料倒入杯中
pureInCup();
//4.加入調味料
addCondiments();
}
/*
* 抽象的基本方法,加調料
*/
protected abstract void addCondiments();
/*
* 抽象的基本方法,泡製飲料
*/
protected abstract void brew() ;
private void pureInCup() {
// TODO Auto-generated method stub
System.out.println("將飲料倒入杯中");
}
/*
* 基本方法,將水煮沸。向下屏蔽細節
* 對所有子類而言是一個共同的行爲,不必向子類做過多地開放。故用private進行修飾
*/
private void boilWater() {
// TODO Auto-generated method stub
System.out.println("將水煮沸");
}
}
2.2 具體子類實現延遲步驟
/*
* 具體子類,提供了咖啡製作的基本實現
*/
public class Coffee extends RefreshBeverage {
@Override
protected void brew() {
// TODO Auto-generated method stub
System.out.println("用沸水沖泡咖啡");
}
@Override
protected void addCondiments() {
// TODO Auto-generated method stub
System.out.println("加入糖和牛奶");
}
}
/*
* 具體子類,提供了茶製作的基本實現
*/
public class Tea extends RefreshBeverage {
@Override
protected void brew() {
// TODO Auto-generated method stub
System.out.println("用80度的熱水浸泡茶葉5分鐘");
}
@Override
protected void addCondiments() {
// TODO Auto-generated method stub
System.out.println("加入檸檬");
}
}
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("咖啡製備中...");
//調用模板方法
RefreshBeverage b1=new Coffee();
b1.prepareBeverageTemplate();
System.out.println("咖啡做好了!");
System.out.println("****************");
System.out.println("茶製備中...");
//調用模板方法
RefreshBeverage b2=new Tea();
b2.prepareBeverageTemplate();
System.out.println("茶做好了!");
}
}
輸出:
咖啡製備中...
將水煮沸
用沸水沖泡咖啡
將飲料倒入杯中
加入糖和牛奶
咖啡做好了!
****************
茶製備中...
將水煮沸
用80度的熱水浸泡茶葉5分鐘
將飲料倒入杯中
加入檸檬
茶做好了!
2.3 鉤子使子類更靈活
/*
* 抽象基類,爲所有子類提供一個算法框架
* 提神飲料
*/
public abstract class RefreshBeverage {
//禁止子類對算法框架做任何的改變.Template模板
/*
* 製備飲料的模板方法
* 封裝了所有子類共同遵循的算法框架
* ctrl+1 可以自動生成方法
*/
public final void prepareBeverageTemplate() {
//1.將水煮沸
boilWater();
//2.泡製飲料
brew();
//3.將飲料倒入杯中
pureInCup();
//用鉤子函數來進行判斷,是否需要加入調味料
if(isCondimentsNeed()) {
//4.加入調味料.
addCondiments();
}
}
/*
* 抽象的基本方法,加調料
*/
protected abstract void addCondiments();
/*
* 抽象的基本方法,泡製飲料
*/
protected abstract void brew() ;
private void pureInCup() {
// TODO Auto-generated method stub
System.out.println("將飲料倒入杯中");
}
/*
* 基本方法,將水煮沸。向下屏蔽細節
* 對所有子類而言是一個共同的行爲,不必向子類做過多地開放。故用private進行修飾
*/
private void boilWater() {
// TODO Auto-generated method stub
System.out.println("將水煮沸");
}
/*
* Hook函數,鉤子函數,提供一個默認或空的實現
* 具體的子類可以自行決定是否掛鉤以及如何掛鉤
* 詢問用戶是否加入調料
*/
protected boolean isCondimentsNeed() {
return true;
}
}
/*
* 具體子類,提供了茶製作的基本實現
*/
public class Tea extends RefreshBeverage {
@Override
protected void brew() {
// TODO Auto-generated method stub
System.out.println("用80度的熱水浸泡茶葉5分鐘");
}
@Override
protected void addCondiments() {
// TODO Auto-generated method stub
System.out.println("加入檸檬");
}
/*
* (non-Javadoc)
* @see com.imooc.pattern.template.RefreshBeverage#isCondimentsNeed()
* 子類通過覆蓋的形式選擇掛載鉤子函數
*/
protected boolean isCondimentsNeed() {
return false;
}
}
輸出:
茶製備中...
將水煮沸
用80度的熱水浸泡茶葉5分鐘
將飲料倒入杯中
茶做好了!
3. 模板方法模式總結
3.1 模板方法模式總結
模板方法模式的實現要素:抽象基類,具體子類
模板方法模式的實現要素
準備一個抽象類,將部分邏輯以具體方法的形式實現,然後聲明一些抽象方法交由子類實現剩餘邏輯,用鉤子方法給予子類更大的靈活性。最後將方法彙總成一個不可改變的模板方法。
模板方法模式的適用場景
(1) 算法或操作遵循相似的邏輯
(2) 重構時把相同的代碼抽取到父類中
(3) 重要、複雜的算法,核心算法設計爲模板算法
模板方法模式的優點
(1) 封裝性好
(2) 複用性好
(3) 屏蔽細節
(4) 便於維護
模板方式的缺點
(1)由於java語言的單繼承性,使用模板方法的子類引入新繼承的時候會遇到困難
3.2 行業案例分享