设计模式之模板方法模式(Template Method)摘录
23種GOF設(shè)計模式一般分為三大類:創(chuàng)建型模式、結(jié)構(gòu)型模式、行為模式。
創(chuàng)建型模式抽象了實例化過程,它們幫助一個系統(tǒng)獨立于如何創(chuàng)建、組合和表示它的那些對象。一個類創(chuàng)建型模式使用繼承改變被實例化的類,而一個對象創(chuàng)建型模式將實例化委托給另一個對象。創(chuàng)建型模式有兩個不斷出現(xiàn)的主旋律。第一,它們都將關(guān)于該系統(tǒng)使用哪些具體的類的信息封裝起來。第二,它們隱藏了這些類的實例是如何被創(chuàng)建和放在一起的。整個系統(tǒng)關(guān)于這些對象所知道的是由抽象類所定義的接口。因此,創(chuàng)建型模式在什么被創(chuàng)建,誰創(chuàng)建它,它是怎樣被創(chuàng)建的,以及何時創(chuàng)建這些方面給予了很大的靈活性。它們允許用結(jié)構(gòu)和功能差別很大的“產(chǎn)品”對象配置一個系統(tǒng)。配置可以是靜態(tài)的(即在編譯時指定),也可以是動態(tài)的(在運行時)。
結(jié)構(gòu)型模式涉及到如何組合類和對象以獲得更大的結(jié)構(gòu)。結(jié)構(gòu)型類模式采用繼承機制來組合接口或?qū)崿F(xiàn)。結(jié)構(gòu)型對象模式不是對接口和實現(xiàn)進行組合,而是描述了如何對一些對象進行組合,從而實現(xiàn)新功能的一些方法。因為可以在運行時刻改變對象組合關(guān)系,所以對象組合方式具有更大的靈活性,而這種機制用靜態(tài)類組合是不可能實現(xiàn)的。
行為模式涉及到算法和對象間職責(zé)的分配。行為模式不僅描述對象或類的模式,還描述它們之間的通信模式。這些模式刻畫了在運行時難以跟蹤的復(fù)雜的控制流。它們將用戶的注意力從控制流轉(zhuǎn)移到對象間的聯(lián)系方式上來。行為類模式使用繼承機制在類間分派行為。行為對象模式使用對象復(fù)合而不是繼承。一些行為對象模式描述了一組對等的對象怎樣相互協(xié)作以完成其中任一個對象都無法單獨完成的任務(wù)。
創(chuàng)建型模式包括:1、FactoryMethod(工廠方法模式);2、Abstract Factory(抽象工廠模式);3、Singleton(單例模式);4、Builder(建造者模式、生成器模式);5、Prototype(原型模式).
結(jié)構(gòu)型模式包括:6、Bridge(橋接模式);7、Adapter(適配器模式);8、Decorator(裝飾模式);9、Composite(組合模式);10、Flyweight(享元模式);11、Facade(外觀模式);12、Proxy(代理模式).
行為模式包括:13、TemplateMethod(模板方法模式);14、Strategy(策略模式);15、State(狀態(tài)模式);16、Observer(觀察者模式);17、Memento(備忘錄模式);18、Mediator(中介者模式);19、Command(命令模式);20、Visitor(訪問者模式);21、Chain of Responsibility(責(zé)任鏈模式);22、Iterator(迭代器模式);23、Interpreter(解釋器模式).
Factory Method:定義一個用于創(chuàng)建對象的接口,讓子類決定將哪一個類實例化。Factory Method使一個類的實例化延遲到其子類。
Abstract Factory:提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口,而無需指定他們具體的類。
Singleton:保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。
Builder:將一個復(fù)雜對象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。
Prototype:用原型實例指定創(chuàng)建對象的種類,并且通過拷貝這個原型來創(chuàng)建新的對象。
Bridge:將抽象部分與它的實現(xiàn)部分分離,使它們都可以獨立地變化。
Adapter:將一個類的接口轉(zhuǎn)換成客戶希望的另外一個接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。
Decorator:動態(tài)地給一個對象添加一些額外的職責(zé)。就擴展功能而言, Decorator模式比生成子類方式更為靈活。
Composite:將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)。Composite使得客戶對單個對象和復(fù)合對象的使用具有一致性。
Flyweight:運用共享技術(shù)有效地支持大量細粒度的對象。
Facade:為子系統(tǒng)中的一組接口提供一個一致的界面, Facade模式定義了一個高層接口,這個接口使得這一子系統(tǒng)更加容易使用。
Proxy:為其他對象提供一個代理以控制對這個對象的訪問。
Template Method:定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。Template Method使得子類可以不改變一個算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。
Strategy:定義一系列的算法,把它們一個個封裝起來, 并且使它們可相互替換。本模式使得算法的變化可獨立于使用它的客戶。
State:允許一個對象在其內(nèi)部狀態(tài)改變時改變它的行為。對象看起來似乎修改了它所屬的類。
Observer:定義對象間的一種一對多的依賴關(guān)系,以便當(dāng)一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知并自動刷新。
Memento:在不破壞封裝性的前提下,捕獲一個對象的內(nèi)部狀態(tài),并在該對象之外保存這個狀態(tài)。這樣以后就可將該對象恢復(fù)到保存的狀態(tài)。
Mediator:用一個中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。
Command:將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數(shù)化;對請求排隊或記錄請求日志,以及支持可取消的操作。
Visitor:表示一個作用于某對象結(jié)構(gòu)中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。
Chain of Responsibility:為解除請求的發(fā)送者和接收者之間耦合,而使多個對象都有機會處理這個請求。將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理它。
Iterator:提供一種方法順序訪問一個聚合對象中各個元素, 而又不需暴露該對象的內(nèi)部表示。
Interpreter:給定一個語言, 定義它的文法的一種表示,并定義一個解釋器, 該解釋器使用該表示來解釋語言中的句子。
???????? Template Method:(1)、意圖:定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。Template Method使得子類可以不改變一個算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。
???????? (2)、適用性:A、一次性實現(xiàn)一個算法的不變的部分,并將可變的行為留給子類來實現(xiàn)。B、各子類中公共的行為應(yīng)被提取出來并集中到一個公共父類中以避免代碼重復(fù)。C、控制子類擴展。
???????? (3)、效果:模板方法是一種代碼復(fù)用的基本技術(shù)。它們在類庫中尤為重要,它們提取了類庫中的公共行為。
???????? (4)、注意事項:A、使用C++訪問控制:在C++中,一個模板方法調(diào)用的原語操作可以被定義為保護成員。這保證它們只被模板方法調(diào)用。必須重定義的原語操作須定義為純虛函數(shù)。模板方法自身不需被重定義;因此可以將模板方法定義為一個非虛成員函數(shù)。B、盡量減少原語操作:定義模板方法的一個重要目的是盡量減少一個子類具體實現(xiàn)該算法時必須重定義的那些原語操作的數(shù)目。需要重定義的操作越多,客戶程序就越冗長。C、命名約定:可以給應(yīng)被重定義的那些操作的名字加上一個前綴以識別它們。
???????? (5)、相關(guān)模式:A、FactoryMethod模式常被模板方法調(diào)用。B、模板方法使用繼承來改變算法的一部分。Strategy使用委托來改變整個算法。
???????? (6)、TemplateMethod:把不變的代碼部分都轉(zhuǎn)移到父類中,將可變的代碼用virtual留給子類重寫。
???????? (7)、Template Method模式實際上就是利用面向?qū)ο笾卸鄳B(tài)的概念實現(xiàn)算法實現(xiàn)細節(jié)和高層接口的松耦合。可以看到Template Method模式采取的是繼承方式實現(xiàn)這一點的,由于繼承是一種強約束性的條件,因此也給Template Method模式帶來一些許多不方便的地方。其關(guān)鍵是將通用算法(邏輯)封裝起來,而將算法細節(jié)讓子類實現(xiàn)(多態(tài))。
???????? Template Method模式獲得一種反向控制結(jié)構(gòu)效果,這也是面向?qū)ο笙到y(tǒng)的分析和設(shè)計中一個原則DIP(依賴倒置:Dependency Inversion Principles)。其含義就是父類調(diào)用子類的操作(高層模塊調(diào)用低層模塊的操作),低層模塊實現(xiàn)高層模塊聲明的接口。這樣控制權(quán)在父類(高層模塊),低層模塊反而要依賴高層模塊。
示例代碼1:
#include <iostream>
#include <vector>
#include <string>using namespace std;class AbstractClass
{
public:void Show(){cout<<"我是"<<GetName()<<endl;}
protected:virtual string GetName() = 0;
};class Naruto : public AbstractClass
{
protected:virtual string GetName(){return "火影史上最帥的六代目----一鳴驚人naruto";}
};class OnePice : public AbstractClass
{
protected:virtual string GetName(){return "我是無惡不作的大海賊----路飛";}
};//客戶端
int main()
{Naruto* man = new Naruto();man->Show();OnePice* man2 = new OnePice();man2->Show();/*result我是火影史上最帥的六代目----一鳴驚人naruto我是我是無惡不作的大海賊----路飛*/return 0;
}
示例代碼2:
Template.h:
#ifndef _TEMPLATE_H_
#define _TEMPLATE_H_class AbstractClass
{
public:virtual ~AbstractClass();void TemplateMethod();
protected:virtual void PrimitiveOperation1() = 0;virtual void PrimitiveOperation2() = 0;AbstractClass();
private:
};class ConcreteClass1 : public AbstractClass
{
public:ConcreteClass1();~ConcreteClass1();
protected:void PrimitiveOperation1();void PrimitiveOperation2();
private:
};class ConcreteClass2 : public AbstractClass
{
public:ConcreteClass2();~ConcreteClass2();
protected:void PrimitiveOperation1();void PrimitiveOperation2();
private:
};#endif//~_TEMPLATE_H_
Template.cpp :
#include "Template.h"
#include <iostream>using namespace std;AbstractClass::AbstractClass()
{}AbstractClass::~AbstractClass()
{}void AbstractClass::TemplateMethod()
{this->PrimitiveOperation1();this->PrimitiveOperation2();
}ConcreteClass1::ConcreteClass1()
{}ConcreteClass1::~ConcreteClass1()
{}void ConcreteClass1::PrimitiveOperation1()
{cout<<"ConcreteClass1 ... PrimitiveOperation1"<<endl;
}void ConcreteClass1::PrimitiveOperation2()
{cout<<"ConcreteClass1 ... PrimitiveOperation2"<<endl;
}ConcreteClass2::ConcreteClass2()
{}ConcreteClass2::~ConcreteClass2()
{}void ConcreteClass2::PrimitiveOperation1()
{cout<<"ConcreteClass2 ... PrimitiveOperation1"<<endl;
}void ConcreteClass2::PrimitiveOperation2()
{cout<<"ConcreteClass2 ... PrimitiveOperation2"<<endl;
}
main.cpp:
#include "Template.h"
#include <iostream>using namespace std;int main()
{AbstractClass* p1 = new ConcreteClass1();AbstractClass* p2 = new ConcreteClass2();p1->TemplateMethod();p2->TemplateMethod();/*resultConcreteClass1 ... PrimitiveOperation1ConcreteClass1 ... PrimitiveOperation2ConcreteClass2 ... PrimitiveOperation1ConcreteClass2 ... PrimitiveOperation2*/return 0;
}
模板方法模式結(jié)構(gòu)圖:
參考文獻:
1、《大話設(shè)計模式C++》
2、《設(shè)計模式精解----GoF23種設(shè)計模式解析》
3、《設(shè)計模式----可復(fù)用面向?qū)ο筌浖幕A(chǔ)》
總結(jié)
以上是生活随笔為你收集整理的设计模式之模板方法模式(Template Method)摘录的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计模式之代理模式(Proxy)摘录
- 下一篇: 设计模式之策略模式(Strategy)摘