1. 程式人生 > >【設計模式】之模板方法模式

【設計模式】之模板方法模式

1.模式動機與定義

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

模板方法是一種行為型模式。

2.模式結構與分析

/**
 * 實現了一個模板方法,定義了演算法的骨架。
 * 具體子類將重新定義primitiveMethod()以實現一個演算法的步驟
 *
 * 注意:是抽象類,不是介面。
 * 為什麼不是介面?因為templateMethod()方法有具體的方法體。
 */
public abstract class AbstractClass {

    public void templateMethod() {
        primitiveOperation1();
        primitiveOperation2();
        System.out.println("這裡是演算法骨架中的一些共用的操作");
    }

    protected abstract void primitiveOperation1();
    protected abstract void primitiveOperation2();
}
/**
 * 具體類A
 */
public class ConcreteClassA extends AbstractClass {

    @Override
    protected void primitiveOperation1() {
        System.out.println("具體類A的方法1實現");
    }

    @Override
    protected void primitiveOperation2() {
        System.out.println("具體類A的方法2實現");
    }
}
/**
 * 具體類B
 */
public class ConcreteClassB extends AbstractClass {

    @Override
    protected void primitiveOperation1() {
        System.out.println("具體類B的方法1實現");
    }

    @Override
    protected void primitiveOperation2() {
        System.out.println("具體類B的方法2實現");
    }
}

客戶端程式碼如下。

public class Client {

    public static void main(String[] args) {
        AbstractClass c;

        c = new ConcreteClassA();
        c.templateMethod();

        System.out.println("----------------");

        c = new ConcreteClassB();
        c.templateMethod();
    }
}
/**
 *
 輸出如下:
 具體類A的方法1實現
 具體類A的方法2實現
 這裡是演算法骨架中的一些共用的操作
 ----------------
 具體類B的方法1實現
 具體類B的方法2實現
 這裡是演算法骨架中的一些共用的操作
 */

3.模式例項與解析

/**
 * 測試試卷類,包含了題目和選項。
 * 學生僅僅填寫答案就可以.
 */
public abstract class TestPaper {

    public void testQuestion1() {
        System.out.println("測試題目1: xxxxxx,下面答案正確的是。A.xxxx B.yyyy C.zzzz D.wwww");
        System.out.println("你的答案為:" + answer1());
    }

    public void testQuestion2() {
        System.out.println("測試題目2: xxxxxx,下面答案正確的是。A.xxxx B.yyyy C.zzzz D.wwww");
        System.out.println("你的答案為:" + answer2());
    }

    public void testQuestion3() {
        System.out.println("測試題目3: xxxxxx,下面答案正確的是。A.xxxx B.yyyy C.zzzz D.wwww");
        System.out.println("你的答案為:" + answer3());
    }

    protected abstract String answer1();
    protected abstract String answer2();
    protected abstract String answer3();
}
/**
 * 學生A的試卷
 */
public class TestPaperA extends TestPaper {

    @Override
    protected String answer1() {
        return "A";
    }

    @Override
    protected String answer2() {
        return "A";
    }

    @Override
    protected String answer3() {
        return "A";
    }
}
/**
 * 學生B的試卷
 */
public class TestPaperB extends TestPaper {

    @Override
    protected String answer1() {
        return "B";
    }

    @Override
    protected String answer2() {
        return "B";
    }

    @Override
    protected String answer3() {
        return "B";
    }
}
public class Client {

    public static void main(String[] args) {
        TestPaper testPaperA = new TestPaperA();
        testPaperA.testQuestion1();
        testPaperA.testQuestion2();
        testPaperA.testQuestion3();

        System.out.println("-------------------------------------");

        TestPaper testPaperB = new TestPaperB();
        testPaperB.testQuestion1();
        testPaperB.testQuestion2();
        testPaperB.testQuestion3();
    }
}
/**
 *輸出如下:
 測試題目1: xxxxxx,下面答案正確的是。A.xxxx B.yyyy C.zzzz D.wwww
 你的答案為:A
 測試題目2: xxxxxx,下面答案正確的是。A.xxxx B.yyyy C.zzzz D.wwww
 你的答案為:A
 測試題目3: xxxxxx,下面答案正確的是。A.xxxx B.yyyy C.zzzz D.wwww
 你的答案為:A
 -------------------------------------
 測試題目1: xxxxxx,下面答案正確的是。A.xxxx B.yyyy C.zzzz D.wwww
 你的答案為:B
 測試題目2: xxxxxx,下面答案正確的是。A.xxxx B.yyyy C.zzzz D.wwww
 你的答案為:B
 測試題目3: xxxxxx,下面答案正確的是。A.xxxx B.yyyy C.zzzz D.wwww
 你的答案為:B
 */

4.模式效果與應用

  • 模板方法模式在一個類中形式化地定義演算法,而由它的子類實現細節的處理。 模板方法模式的優勢是,在子類定義詳細的處理演算法時不會改變演算法的結構。模板方法模式就是體現繼承優勢的模式之一
  • 模板方法是一種程式碼複用的基本技術,它們在類庫中尤為重要,它們提取了類庫中的公共行為。 其主要應用於框架設計,以確保父類控制處理流程的邏輯順序(如框架的初始化)。
  • 在模板方法模式中,子類不顯式呼叫父類的方法,而是通過覆蓋父類的方法來實現某些具體的業務邏輯,父類控制對子類的呼叫,這種機制被稱為好萊塢原則(Hollywood Principle),即“不要給我們打電話,我們會給你打電話(Don‘t call us, we’ll call you)”。在模板方法模式中,好萊塢原則體現在:子類不需要呼叫父類,而通過父類來呼叫子類,將某些步驟的實現寫在子類中,由父類來控制整個過程。