1. 程式人生 > >十四、模版方法設計模式

十四、模版方法設計模式

1. 模版方法模式介紹

在面向物件開發過程中,通常我們會遇到這樣的一個問題:我們知道一個演算法的關鍵步驟,並確定了這些步驟的執行順序。但是某些步驟的具體實現是未知的,或者說某些步驟的實現與具體的環境相關。

例如: 去食堂吃飯一般都有這樣的步驟:
1. 排隊
2. 買飯
3. 吃飯

這三個步驟一般都是固定的,但是不同的菜,三個步驟的具體操作是不確定的。
不同的菜買不同的原料;不同的菜不同的切法;不同的菜不同的做法。
但是這三個步驟一定是固定的。

2. 模版方法模式的使用場景

  • 多個子類有公有的方法,並且邏輯基本相同。
  • 重要、複雜的演算法,可以把核心演算法設計為模板演算法,周邊的相關細節功能由各個子類實現。
  • 重構時,模版方法模式是一個經常使用的模式,把相同的程式碼抽取到父類中,然後通過鉤子函式約定其行為。

3. 模版方法模式的UML類圖

模版方法模式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.總結

  • 模版方法比較常見,其目的就是對流程進行封裝。封裝不可變的,擴充套件可變的。