模板方法模式
模板方法模式:定義一個操作中的算法的骨架,而將一些步驟延遲到子類中.模板方法使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟.
注意:本博文代碼GitHub倉庫
簡而言之就是以下幾點:
- 父類定義一個功能方法,其邏輯固定;
- 父類的功能方法中,對於具體情況分爲可變部分和不可變部分;
- 子類繼承父類,根據自身情況重寫可變部分。
設計思路分析
針對與以上幾點我們可以得出以下幾點:
- 父類中定義一個不可更改的方法,確定整個方法的功能邏輯,用final關鍵字修飾不可更改不可重寫;
- 父類對於邏輯可變部分,定義抽象方法,將該步驟延遲到子類中實現;
- 父類對於邏輯不變部分,定義具體方法,且用final關鍵字修飾不可更改不可重寫;
- 父類可以定義某些邏輯判斷方法來控制某些方法是否執行,子類可以通過重寫邏輯判斷方法進行對整體算法的部分修改;
模板方法類
模式類結構圖:
模式的結構說明
模板方法模式包含以下主要角色:
- 抽象類(Abstract Class):主要定義算法的輪廓和框架。它由一個模板方法和若干個基本方法構成。
- 模板方法:定義算法的輪廓和骨架,確定了若干語句和基礎方法的調用順序,如本類中的templateMethod。
- 基本方法:定義模板方法中的具體某一個具體步驟,分爲抽象方法,具體方法以及鉤子方法。
基本方法:
- 抽象方法:在抽象類中申明,由具體子類實現。主要用於改變部分,延遲到子類實現。
- 具體方法:在抽象類中已經實現,在具體子類中可以繼承或重寫它。
- 鉤子方法:在抽象類中已經實現,包括用於判斷的邏輯方法和需要子類重寫的空方法兩種。
- 具體子類(Concrete Class):實現抽象類中所定義的抽象方法和鉤子方法,它們是一個頂級邏輯的一個組成步驟。
Demo
AbstractClass.java
package com.frank.design.TemplateMethod.Demo;
/**
* 模板方法模式父類,用於定義所有不變的行爲,從而去除子類重複代碼,提高代碼複用性。
* @AUTHOR:Frank
* @DATE:05/23/2019
*/
public abstract class AbstractClass {
//protected 修飾抽象方法是爲了該方法不對外開發,只針對與實現類開放
protected abstract void primitiveOperation1();
protected abstract void primitiveOperation2();
protected abstract void primitiveOperation3();
// 條件判斷方法,判斷某個方法是否可以執行
protected boolean primitiveOperation4(){
return false;
}
protected final void primitiveOperation5(){
System.out.println("can't change method:primitiveOperation5");
}
//final 修飾是保證整體調用方法不被改動,保證邏輯的不可變性
public final void tmplateMethod(){
System.out.println("whole method start");
primitiveOperation1();
primitiveOperation2();
if(primitiveOperation4()){
primitiveOperation3();
}
primitiveOperation5();
System.out.println("whole method end");
}
}
ConcreteClassA .java
package com.frank.design.TemplateMethod.Demo;
/**
* 子類:對於父類方法的不同實現
* @AUTHOR:Frank
* @DATE:05/23/2019
*/
public class ConcreteClassA extends AbstractClass{
@Override
public void primitiveOperation1() {
System.out.println("This is ConcreteClassA's method : primitiveOperation1");
}
@Override
public void primitiveOperation2() {
System.out.println("This is ConcreteClassA's method : primitiveOperation2");
}
@Override
protected void primitiveOperation3() {
System.out.println("This is ConcreteClassA's method : primitiveOperation3");
}
}
ConcreteClassB.java
package com.frank.design.TemplateMethod.Demo;
/**
* 子類:對於父類方法的不同實現
* @AUTHOR:Frank
* @DATE:05/23/2019
*/
public class ConcreteClassB extends AbstractClass{
@Override
public void primitiveOperation1() {
System.out.println("This is ConcreteClassB's method : primitiveOperation1");
}
@Override
public void primitiveOperation2() {
System.out.println("This is ConcreteClassB's method : primitiveOperation2");
}
@Override
protected void primitiveOperation3() {
System.out.println("This is ConcreteClassB's method : primitiveOperation3");
}
@Override
protected boolean primitiveOperation4() {
return true;
}
}
總結
模板方法模式的優缺點
優點
- 通過封裝不可變部分到父類中實現,子類負責實現可變部分,去除子類中重複代碼。
- 父類中封裝了公共代碼,有助於提高代碼複用性。
- 子類實現算法細節,有助於子類對於算法細節的擴展。
- 通過父類調用子類方法,子類增加拓展算法實現,符合“開放-封閉原則”。
缺點
一般來講,抽象類會定義相關基礎變量、方法,由子類負責繼承實現。但是模板方法模式父類調用子類具體實現,可讀性降低。
模板方法模式的適用場景
- 多個子類有共有的方法,並且邏輯基本相同。
- 重要、複雜的算法,可以把核心算法設計爲模板方法,周邊的相關細節功能則由各個子類實現。
- 重構時,模板方法是一個經常使用的方法,把相同的代碼抽取到父類中,然後通過構造函數約束其行爲。