加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • 1 模板方法
    • 2 實(shí)例
    • 總結(jié)
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

大話設(shè)計(jì)模式解讀07-模板方法

09/30 15:35
935
閱讀需 12 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

上篇文章,介紹了《大話設(shè)計(jì)模式》的第9章——原型模式。

本篇,來介紹《大話設(shè)計(jì)模式》的第10章——模板方法。并通過C++代碼實(shí)現(xiàn)實(shí)例代碼的功能。

1 模板方法

模板方法模式(TemplateMethod):定義一個(gè)操作中的算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。

2 實(shí)例

背景:書中小故事,抄題目做題,看不清黑板,題目抄錯(cuò),導(dǎo)致做題肯定是錯(cuò)的。

題目:用代碼的形式來實(shí)現(xiàn)。

2.1 版本一:?jiǎn)为?dú)的試卷類

版本一的實(shí)現(xiàn)比較簡(jiǎn)單,學(xué)生甲和學(xué)生乙單獨(dú)抄試卷做題,分別實(shí)現(xiàn)兩個(gè)類。

2.1.1 兩個(gè)同學(xué)分別抄題目作答

定義兩個(gè)類,實(shí)現(xiàn)兩個(gè)同學(xué)獨(dú)自抄題做題:

// 學(xué)生甲抄的試卷
class TestPaperA
{
public:
    // 試題1
    void TestQuestion1()
    {
        printf("1.在TCP/IP協(xié)議棧中,應(yīng)用層協(xié)議數(shù)據(jù)單元為(). A.消息 B.段 C.用戶數(shù)據(jù)報(bào) D.幀n");
        printf("答案: Bn");
    }    
    
    // 試題2
    void TestQuestion2()
    {
        printf("2.在C語言中,char型數(shù)據(jù)在內(nèi)存中的存儲(chǔ)形式是(). A.補(bǔ)碼 B.反碼 C.原碼 D.ASCII碼n");
        printf("答案: Dn");
    }    
    
    // 試題3
    void TestQuestion3()
    {
        printf("3.某計(jì)算機(jī)字長(zhǎng)是32位,存儲(chǔ)容量是256KB, 按字編址的尋址范圍是(). A.128K B.64K C.32K D.16Kn");
        printf("答案: Bn");
    }    
};

// 學(xué)生乙抄的試卷
class TestPaperB
{
public:
    // 試題1
    void TestQuestion1()
    {
        printf("1.在TCP/IP協(xié)議棧中,應(yīng)用層協(xié)議數(shù)據(jù)單元為(). A.消息 B.段 C.用戶數(shù)據(jù)報(bào) D.幀n");
        printf("答案: Bn");
    }    
    
    // 試題2
    void TestQuestion2()
    {
        printf("2.在C語言中,char型數(shù)據(jù)在內(nèi)存中的存儲(chǔ)形式是(). A.補(bǔ)碼 B.反碼 C.原碼 D.ASCII碼n");
        printf("答案: Bn");
    }    
    
    // 試題3
    void TestQuestion3()
    {
        printf("3.某計(jì)算機(jī)字長(zhǎng)是32位,存儲(chǔ)容量是256KB, 按字編址的尋址范圍是(). A.128K B.64K C.32K D.16Kn");
        printf("答案: Cn");
    }    
};

2.1.2 主函數(shù)

首先,實(shí)例化兩個(gè)同學(xué),抄題做題,

然后,就可以調(diào)用展示接口來顯示出來了。

int main()
{
    printf("學(xué)生甲抄的試卷:n");
    TestPaperA studentA;
    studentA.TestQuestion1();
    studentA.TestQuestion2();
    studentA.TestQuestion3();
	
	printf("n學(xué)生乙抄的試卷:n");
    TestPaperB studentB;
    studentB.TestQuestion1();
    studentB.TestQuestion2();
    studentB.TestQuestion3();
    
    return 0;
}

代碼運(yùn)行效果如下:

下面來看版本二。

2.2 版本二:對(duì)試卷題目封裝為一個(gè)類

版本二,是將題目封裝為一個(gè)類,這樣就確保兩個(gè)同學(xué)做的題目是一樣的:

2.2.1 試題類

// 計(jì)算機(jī)試題
class TestPaper
{
public:
    // 試題1
    void TestQuestion1()
    {
        printf("1.在TCP/IP協(xié)議棧中,應(yīng)用層協(xié)議數(shù)據(jù)單元為(). A.消息 B.段 C.用戶數(shù)據(jù)報(bào) D.幀n");
    }    
    
    // 試題2
    void TestQuestion2()
    {
        printf("2.在C語言中,char型數(shù)據(jù)在內(nèi)存中的存儲(chǔ)形式是(). A.補(bǔ)碼 B.反碼 C.原碼 D.ASCII碼n");
    }    
    
    // 試題3
    void TestQuestion3()
    {
        printf("3.某計(jì)算機(jī)字長(zhǎng)是32位,存儲(chǔ)容量是256KB, 按字編址的尋址范圍是(). A.128K B.64K C.32K D.16Kn");
    }    
};

2.2.2 ?兩個(gè)同學(xué)分別作答

定義的兩個(gè)同學(xué)類,繼承題目類,然后僅根據(jù)題目作答即可。

// 學(xué)生甲抄的試卷
class TestPaperA : public TestPaper
{
public:
    // 試題1
    void TestQuestion1()
    {
        TestPaper::TestQuestion1();
        printf("答案: Bn");
    }    
    
    // 試題2
    void TestQuestion2()
    {
        TestPaper::TestQuestion2();
        printf("答案: Dn");
    }    
    
    // 試題3
    void TestQuestion3()
    {
        TestPaper::TestQuestion3();
        printf("答案: Bn");
    }    
};

// 學(xué)生乙抄的試卷
class TestPaperB : public TestPaper
{
public:
    // 試題1
    void TestQuestion1()
    {
        TestPaper::TestQuestion1();
        printf("答案: Bn");
    }    
    
    // 試題2
    void TestQuestion2()
    {
        TestPaper::TestQuestion2();
        printf("答案: Bn");
    }    
    
    // 試題3
    void TestQuestion3()
    {
        TestPaper::TestQuestion3();
        printf("答案: Cn");
    }    
};

2.2.3 主函數(shù)

主函數(shù)不用改。

代碼運(yùn)行效果如下:

2.3 版本三:模板方法模式

版本三,模板方法模式。在版本二中,每個(gè)同學(xué)的類中,還需要有重復(fù)的printf("答案: Xn");這類代碼,實(shí)際上,每個(gè)同學(xué)作答不一樣的地方,只是ABCD的這4個(gè)選項(xiàng)。

因此,可以將重復(fù)的printf也提升到試卷類中,并對(duì)ABCD的這4個(gè)選項(xiàng)的選擇提供一個(gè)虛方法,在運(yùn)行時(shí)由子類(同學(xué)類)來實(shí)現(xiàn):

2.3.1 試題類

// 計(jì)算機(jī)試題
class TestPaper
{
public:
    // 試題1
    void TestQuestion1()
    {
        printf("1.在TCP/IP協(xié)議棧中,應(yīng)用層協(xié)議數(shù)據(jù)單元為(). A.消息 B.段 C.用戶數(shù)據(jù)報(bào) D.幀n");
        printf("答案: %sn", Answer1().c_str());
    }    
    
    // 試題2
    void TestQuestion2()
    {
        printf("2.在C語言中,char型數(shù)據(jù)在內(nèi)存中的存儲(chǔ)形式是(). A.補(bǔ)碼 B.反碼 C.原碼 D.ASCII碼n");
        printf("答案: %sn", Answer2().c_str());
    }    
    
    // 試題3
    void TestQuestion3()
    {
        printf("3.某計(jì)算機(jī)字長(zhǎng)是32位,存儲(chǔ)容量是256KB, 按字編址的尋址范圍是(). A.128K B.64K C.32K D.16Kn");
        printf("答案: %sn", Answer3().c_str());
    }  
    
protected: 
    virtual std::string Answer1() {return "";};
    virtual std::string Answer2() {return "";};
    virtual std::string Answer3() {return "";};
};

2.3.2 ?兩個(gè)同學(xué)分別作答

// 學(xué)生甲抄的試卷
class TestPaperA : public TestPaper
{
protected:
    // 試題1
    std::string Answer1() {return "B";};  
    
    // 試題2
    std::string Answer2() {return "D";};    
    
    // 試題3
    std::string Answer3() {return "B";};     
};

// 學(xué)生乙抄的試卷
class TestPaperB : public TestPaper
{
protected:
    // 試題1
    std::string Answer1() {return "B";};  
    
    // 試題2
    std::string Answer2() {return "B";};    
    
    // 試題3
    std::string Answer3() {return "C";};    
};

2.3.3 主函數(shù)

主函數(shù)不用改。

代碼運(yùn)行效果如下:

總結(jié)

本篇介紹了設(shè)計(jì)模式中的模板方法模式,并通過學(xué)生抄寫題目作答的實(shí)例,使用C++編程,來演示模板方法模式的使用。

文章推薦

《大話設(shè)計(jì)模式》解讀01-簡(jiǎn)單工廠模式

《大話設(shè)計(jì)模式》解讀02-策略模式

《大話設(shè)計(jì)模式》解讀03-裝飾模式

《大話設(shè)計(jì)模式》解讀05-工廠方法

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

控制科學(xué)與工程碩士,日常分享單片機(jī)、嵌入式、C/C++、Linux等學(xué)習(xí)經(jīng)驗(yàn)干貨~