Java設計模式之(十三)——模板方法模式

YSOcean發表於2021-12-02

1、什麼是模板模式?

Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.

模板方法模式(Template Method Pattern):定義一個操作中的演算法的框架, 而將一些步驟延遲到子類中。 使得子類可以不改
變一個演算法的結構即可重定義該演算法的某些特定步驟。

說人話:父類别範本方法定義不變的流程,子類重寫流程中的方法。

2、模板模式定義

image-20210923083619120

①、AbstractClass 抽象模板

一、基本方法

上面的 baseOperation() 或者 customOperation() 方法,也叫基本操作,是由子類實現的方法,並且在模板方法中被呼叫。

基本方法儘量設計為protected型別, 符合迪米特法則, 不需要暴露的屬性或方法儘量不要設定為protected型別。 實現類若非必要, 儘量不要擴大父類中的訪許可權。

二、模板方法

上面的 templateMethod() 方法,可以有一個或者幾個,實現對基本方法的排程,完成固定的邏輯。

為了防止惡意操作,通常模板方法都加上 final 關鍵字,不允許覆寫。

②、ConcreteClass 具體模板

實現父類定義的一個或多個抽象方法,也就是父類定義的基本方法在子類中得以實現。

3、模板模式通用程式碼

public abstract class AbstractClass {
    // 共同的且繁瑣的操作
    private void baseOperation() {
        // do something
    }

    // 由子類定製的操作
    protected abstract void customOperation();

    // 模板方法定義的框架
    public final void templateMethod() {
        /**
         * 呼叫基本方法,完成固定邏輯
         */
        baseOperation();
        customOperation();
    }

}
public class ConcreteClass1 extends AbstractClass{

    @Override
    protected void customOperation() {
        // 具體模板1 業務邏輯
        System.out.println("具體模板1:customOperation()");
    }
}
public class ConcreteClass2 extends AbstractClass{
    @Override
    protected void customOperation() {
        // 具體模板2 業務邏輯
        System.out.println("具體模板2:customOperation()");
    }
}

測試:

public class TemplateClient {
    public static void main(String[] args) {
        AbstractClass abstractClass1 = new ConcreteClass1();
        AbstractClass abstractClass2 = new ConcreteClass2();
        applyTemplate(abstractClass1);
        applyTemplate(abstractClass2);
    }

    public static void applyTemplate(AbstractClass abstractClass){
        abstractClass.templateMethod();
    }
}

4、模板模式優點

①、封裝不變部分, 擴充套件可變部分

把認為是不變部分的演算法封裝到父類實現, 而可變部分的則可以通過繼承來繼續擴充套件。

②、提取公共部分程式碼, 便於維護

③、行為由父類控制, 子類實現

基本方法是由子類實現的, 因此子類可以通過擴充套件的方式增加相應的功能, 符合開閉原則。

5、模板模式缺點

①、子類執行的結果影響了父類的結果,這和我們平時設計習慣顛倒了,在複雜專案中,會帶來閱讀上的難度。

②、可能引起子類氾濫和為了繼承而繼承的問題

6、回撥

為了解決模板模式的缺點,我們可以利用回撥函式代替子類繼承。

image-20210923084711611
public interface Callback {
    void customOperation();
}
public class SubCallback implements Callback{
    @Override
    public void customOperation() {
        System.out.println("SubCallback customOperation");
    }
}
/**
 * 模板類
 * 宣告為 final,無法被繼承
 */
public final class Template {
    private void baseOperation(){
        System.out.println("模板類公共操作");
    }

    public void templateMethod(Callback callback){
        baseOperation();
        callback.customOperation();
    }
}

測試:

public class TemplateClient {
    public static void main(String[] args) {
        Template template = new Template();
        applyTemplate(template);
    }

    public static void applyTemplate(Template template){
        Callback callback = new SubCallback();
        template.templateMethod(callback);
    }
}

Template是一個穩定的final類,無法被繼承,不存在子類行為影響父類結果的問題,而Callback是一個介面,為了繼承而繼承的問題消失了。

相關文章