首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

模板方法模式:從抄試卷到設計模式的演進

     編輯:關於C語言

前言:一場關於抄試卷的啟示

故事始於小菜面試歸來,大鳥詢問感受,小菜感嘆「書到用時方恨少」。隨後話題轉向微軟認證考試的題庫風波,以及大鳥童年抄錯題的經歷。大鳥於是讓小菜寫一段「抄題」代碼,作為引子引出今天的主角——模板方法模式。

初版代碼:重複與脆弱

小菜寫了兩個類 TestPaperA 和 TestPaperB,分別代表兩位學生的試卷。每個類都完整實現了三道題的題目與答案:

class TestPaperA {
public:
    void TestQuestion1() {
        printf("楊過得到……玄鐵可能是【】a.球磨鑄鐵 b.馬口鐵 c.高速合金鋼 d.碳塑纖維 ");
        printf("答案: b ");
    }
    void TestQuestion2() { /* 題目與答案 */ }
    void TestQuestion3() { /* 題目與答案 */ }
};
// TestPaperB 結構相同,唯答案不同

小菜發現:題目完全一致,只有答案不同。這導致代碼極難維護——若老師改題目,兩個類都要改;若抄錯一題,後果嚴重。

重構靈感:抽象出「試卷」父類

大鳥提示:「老師出一份試卷,打印多份,學生只填答案。」於是將不變的題目放入父類,將變化的答案定義為抽象方法,強制子類實現。這就是模板方法模式的核心思想:

在抽象類中定義算法骨架,將某些步驟延遲到子類實現,不改變算法結構前提下重新定義步驟細節。

UML 類圖

Template Method Pattern UML

模式實現代碼

class TestPaper {
public:
    void TestQuestion1() {
        printf("楊過得到……玄鐵可能是【】a.球磨鑄鐵 b.馬口鐵 c.高速合金鋼 d.碳塑纖維 ");
        printf("答案: %c ", Answer1());
    }
    void TestQuestion2() {
        printf("楊過、程英……造成【】a.使這種植物不再害人 b.使一種珍稀物種滅絕 … ");
        printf("答案: %c ", Answer2());
    }
    void TestQuestion3() {
        printf("藍鳳凰致使……會給他們開什麼藥【】a.阿司匹林 b.牛黃解毒片 c.氟哌酸 … ");
        printf("答案: %c ", Answer3());
    }
protected:
    virtual char Answer1() = 0;
    virtual char Answer2() = 0;
    virtual char Answer3() = 0;
};

class TestPaperA : public TestPaper {
protected:
    char Answer1() override { return 'b'; }
    char Answer2() override { return 'a'; }
    char Answer3() override { return 'c'; }
};

class TestPaperB : public TestPaper {
protected:
    char Answer1() override { return 'd'; }
    char Answer2() override { return 'b'; }
    char Answer3() override { return 'a'; }
};

現在 main() 僅需實例化具體試卷類,調用繼承自父類的 TestQuestion* 方法即可。題目邏輯集中維護,答案由子類決定,完美解耦。

總結

  • 模板方法:父類定義算法流程(如 TestQuestion1),調用受保護的抽象方法(Answer1)。
  • 好萊塢原則:「別調用我們,我們會調用你」——父類控制流程,子類填充細節。
  • 適用場景:多個子類共享相同算法結構,僅部分步驟實現不同。

從「抄試卷」到「模板方法」,我們看到設計模式如何將現實世界的最佳實踐轉化為軟體架構的靈活骨架。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved