設計模式之模板方法

前言

模板方法是本人認爲23種設計模式最簡單的。其根本就是巧妙運用java的繼承機制,下面爲你們以一一講來.java

什麼是模板方法模式

定義一個操做中的算法的框架,而將一些步驟延遲到子類中。使得子類能夠不改變一個算法的結構便可重定義該算法的某些特定邏輯。

UML類圖

圖片描述

父類中具備兩種方法,一種是基本方法,供子類複寫,另外一種是模板方法,用來調度基本方法,至關於定義一個框架。子類經過複寫基本方法,調用父類的模板方法就是模板方法的體現。算法

使用場景

  1. 子類具備相同的方法,而且邏輯基本相同
  2. 代碼重構時,模板方法會常常使用到,而後經過鉤子函數(見模板方法擴展)約束其行爲。

代碼分析

public abstract class AbstractDoctor {

    //瞭解病情
    protected abstract void knowAboutSymptoms();
    //分析病情
    protected abstract void analysisIllness();
    //治療患者
    protected abstract void curePatient();
        
    public void work() {
        knowAboutSymptoms();
        analysisIllness();
        curePatient();
    }
}
public class ChineseDoctor extends AbstractDoctor {

    @Override
    protected void knowAboutSymptoms() {
        System.out.println("中醫經過望聞問切瞭解病人病情");
    }
    @Override
    protected void analysisIllness() {
        System.out.println("得知病情後,經過本身豐富的經驗分析病情,制定治療方案");
    }
    @Override
    protected void curePatient() {
        System.out.println("根據治療方案給你抓中藥");
    }
}
public class WestDoctor extends AbstractDoctor {
    @Override
    protected void knowAboutSymptoms() {
        System.out.println("簡單詢問,就讓你去拍個片");
    }

    @Override
    protected void analysisIllness() {
        System.out.println("根據x光片,分析病人病情,制定治療方案");
    }

    @Override
    protected void curePatient() {
        System.out.println("打針,輸液,藥片各來一打,包治百病");
    }
}
public class Client {


    public static void main(String[] args) {
        AbstractDoctor chineseDoctotr = new ChineseDoctor();
        chineseDoctotr.work();

        System.out.println("===============華麗的分隔符========================");

        AbstractDoctor westDoctor = new WestDoctor();
        westDoctor.work();

    }
}

測試結果:
中醫經過望聞問切瞭解病人病情
得知病情後,經過本身豐富的經驗分析病情,制定治療方案
根據治療方案給你抓中藥
===============華麗的分隔符========================
簡單詢問,就讓你去拍個片
根據x光片,分析病人病情,制定治療方案
打針,輸液,藥片各來一打,包治百病

無論你是中醫仍是西醫,你的工做就是治病救人,工做流程也基本相同,都是瞭解病情,分析病情,治療病人這個流程。在父類中定義一個算法來控制流程,具體實現交給具體子類,再由子類調用父類的work(模板方法)進行運做。設計模式

模板方法模式的擴展

要知道,直到今天醫療資源也是很寶貴的資源。有的病人裝病,有的人送到醫院已經徹底死去沒有生命象徵,對於這些病人咱們就沒有必要再去治療了。那如何去控制呢?咱們能夠經過鉤子函數約束其行爲。框架

public abstract class AbstractDoctor {

    protected boolean checkIsCure =true;

    //瞭解病情
    protected abstract void knowAboutSymptoms();
    //分析病情
    protected abstract void analysisIllness();
    //治療患者
    protected abstract void curePatient();

    //檢查病人是否須要治療,默認須要
    //鉤子函數
    protected boolean checkIsCure(){
        return true;
    }

    public void work() {
        knowAboutSymptoms();
        analysisIllness();
        if (checkIsCure()){
            curePatient();
        }
    }

}
public class ChineseDoctor extends AbstractDoctor {

    @Override
    public void knowAboutSymptoms() {
        System.out.println("中醫經過望聞問切瞭解病人病情");
    }
    @Override
    public void analysisIllness() {
        System.out.println("得知病情後,經過本身豐富的經驗分析病情,制定治療方案");
    }
    @Override
    public void curePatient() {
        System.out.println("根據治療方案給你抓中藥");
    }
    @Override
    protected boolean checkIsCure(){
        return super.checkIsCure;
    }

    protected void setCheckIsCure(boolean isCure){
        super.checkIsCure=isCure;
    }
}
public class Client {


    public static void main(String[] args) {
        ChineseDoctor chineseDoctotr = new ChineseDoctor();
        chineseDoctotr.setCheckIsCure(false);
        chineseDoctotr.work();

        System.out.println("===============華麗的分隔符========================");

        AbstractDoctor westDoctor = new WestDoctor();
        westDoctor.work();

    }
}

測試結果:
中醫經過望聞問切瞭解病人病情
得知病情後,經過本身豐富的經驗分析病情,制定治療方案
===============華麗的分隔符========================
簡單詢問,就讓你去拍個片
根據x光片,分析病人病情,制定治療方案
打針,輸液,藥片各來一打,包治百病

經過鉤子函數給中醫賦予了若病人治療無聊,則能夠選擇不治療。其實鉤子函數就是子類方法決定模板方法的執行結果,這樣就靈活了許多。ide

總結

模板方法模式就是在模板方法中按照必定的規則和順序調用基本方法,具體到前面的例子就是先調用knowAboutSymptoms(),再調用analysisIllness(),而後調用checkIsCure()選擇是否執行curePatient()。
按照咱們的設計習慣抽象類負責定義,實現類負責實現具體邏輯,而模板方法確實抽象類定義了部分抽象方法,由子類實現,子類執行的結果影響到了父類的結果,因此其最大的缺點就是增大了閱讀代碼的難度。其最大的優勢就是封裝了不變部分,擴展了可變部分,提取公共代碼,利於維護。函數

相關文章
相關標籤/搜索