十四、模版方法設計模式
阿新 • • 發佈:2019-01-26
1. 模版方法模式介紹
在面向物件開發過程中,通常我們會遇到這樣的一個問題:我們知道一個演算法的關鍵步驟,並確定了這些步驟的執行順序。但是某些步驟的具體實現是未知的,或者說某些步驟的實現與具體的環境相關。
例如: 去食堂吃飯一般都有這樣的步驟:
1. 排隊
2. 買飯
3. 吃飯
這三個步驟一般都是固定的,但是不同的菜,三個步驟的具體操作是不確定的。
不同的菜買不同的原料;不同的菜不同的切法;不同的菜不同的做法。
但是這三個步驟一定是固定的。
2. 模版方法模式的使用場景
- 多個子類有公有的方法,並且邏輯基本相同。
- 重要、複雜的演算法,可以把核心演算法設計為模板演算法,周邊的相關細節功能由各個子類實現。
- 重構時,模版方法模式是一個經常使用的模式,把相同的程式碼抽取到父類中,然後通過鉤子函式約定其行為。
3. 模版方法模式的UML類圖
角色介紹:
AbsTemplate: 抽象類,定義了一套演算法框架
ConcreteImplA:具體實現類A
ConcreteImplB:具體實現了B
4. 模版方法模式的簡單實現
下面用程式碼模擬食堂買飯的情景:
- (1)、定義一個抽象模版:
在eatDinner方法裡面依次順序執行三個方法。
public abstract class EatDinner {
protected void queue() {
System.out .println("排隊");
}
protected void buy() {
System.out.println("買飯");
}
protected void eat() {
System.out.println("吃飯");
}
//市場吃飯的步驟
public final void eatDinner() {
queue();
buy();
eat();
}
}
- (2)、兩個具體的實現類AEatDinner、BEatDinner:
public class AEatDinner extends EatDinner {
@Override
protected void queue() {
System.out.println("排在A隊");
}
@Override
protected void buy() {
System.out.println("買雙份");
}
@Override
protected void eat() {
System.out.println("在食堂吃");
}
}
BEatDinner:
public class BEatDinner extends EatDinner {
@Override
protected void queue() {
System.out.println("排在B隊");
}
@Override
protected void buy() {
System.out.println("買一份");
}
@Override
protected void eat() {
System.out.println("帶宿舍吃飯");
}
}
- (3)、測試類:
public class Client {
public static void main(String[] args) {
EatDinner aEatDinner= new AEatDinner();
EatDinner bEatDinner = new BEatDinner();
aEatDinner.eatDinner();
System.out.println("------");
bEatDinner.eatDinner();
}
}
5. 模版方法模式在Android原始碼中
在Android原始碼中,模版設計模式比較常見,Activity的生命週期本身就是一個模版設計模式,這裡就不具體分析了,相信大家在開始學習Android的時候,都已經對Activity的生命週期有所瞭解。
6. 模版方法模式在Android開發中:
這點就簡單說一下,我們在onCreate方法中定義一下三個方法,自定義生命週期,用來進行相應的操作:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initVariables();
initView();
initData();
}
//初始化變數
private void initVariables() {
}
//初始化View
private void initView() {
}
//初始化資料
private void initData() {
}
}
7.總結
- 模版方法比較常見,其目的就是對流程進行封裝。封裝不可變的,擴充套件可變的。