設計模式(-)

設計模式分爲三種類型

創建型模式:單例模式、抽象工廠模式、建造者模式、工廠模式、原型模式。
結構型模式:適配器模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式。
行爲型模式:模版方法模式、命令模式、迭代器模式、觀察者模式、中介者模式、備忘錄模式、解釋器模式、狀態模式、策略模式、職責鏈模式、訪問者模式。


Abstract Factory(抽象工廠模式):提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
Adapter(適配器模式):將一個類的接口轉換成客戶希望的另外一個接口。Adapter模式使得原本由於接口不兼容而不能一起工作的那些類可以一起工作。
Bridge(橋接模式):將抽象部分與它的實現部分分離,使它們都可以獨立地變化。
Builder(建造者模式):將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
Chain of Responsibility(職責鏈模式):爲解除請求的發送者和接收者之間耦合,而使多個對象都有機會處理這個請求。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它。
Command(命令模式):將一個請求封裝爲一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可取消的操作。
Composite(組合模式):將對象組合成樹形結構以表示“部分-整體”的層次結構。它使得客戶對單個對象和複合對象的使用具有一致性。
Decorator(裝飾模式):動態地給一個對象添加一些額外的職責。就擴展功能而言, 它比生成子類方式更爲靈活。
Facade(外觀模式):爲子系統中的一組接口提供一個一致的界面,Facade模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
Factory Method(工廠模式):定義一個用於創建對象的接口,讓子類決定將哪一個類實例化。Factory Method使一個類的實例化延遲到其子類。
Flyweight(享元模式):運用共享技術有效地支持大量細粒度的對象。
Interpreter(解析器模式):給定一個語言, 定義它的文法的一種表示,並定義一個解釋器, 該解釋器使用該表示來解釋語言中的句子。
Iterator(迭代器模式):提供一種方法順序訪問一個聚合對象中各個元素,而又不需暴露該對象的內部表示。
Mediator(中介模式):用一箇中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的交互。
Memento(備忘錄模式):在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。這樣以後就可將該對象恢復到保存的狀態。
Observer(觀察者模式):定義對象間的一種一對多的依賴關係,以便當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並自動刷新。
Prototype(原型模式):用原型實例指定創建對象的種類,並且通過拷貝這個原型來創建新的對象。
Proxy(代理模式):爲其他對象提供一個代理以控制對這個對象的訪問。
Singleton(單例模式):保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。 單例模式是最簡單的設計模式之一,但是對於Java的開發者來說,它卻有很多缺陷。在九月的專欄中,David Geary探討了單例模式以及在面對多線程(multi-threading)、類裝載器(class loaders)和序列化(serialization)時如何處理這些缺陷。
State(狀態模式):允許一個對象在其內部狀態改變時改變它的行爲。對象看起來似乎修改了它所屬的類。
Strategy(策略模式):定義一系列的算法,把它們一個個封裝起來, 並且使它們可相互替換。本模式使得算法的變化可獨立於使用它的客戶。
Template Method(模板方法模式):定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。Template Method使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。
Visitor(訪問者模式):表示一個作用於某對象結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

設計原則

面向對象有幾個原則:開閉原則(Open Closed Principle,OCP)

                                       里氏代換原則(Liskov Substitution Principle,LSP)

                                       依賴倒轉原則(Dependency Inversion Principle,DIP)

                                       接口隔離原則(Interface Segregation Principle,ISP)

                                      合成/聚合複用原則(Composite/Aggregate Reuse Principle,CARP)

                                      最小知識原則(Principle of Least Knowledge,PLK,也叫迪米特法則)

開閉原則具有理想主義的色彩,它是面向對象設計的終極目標。其他幾條,則可以看做是開閉原則的實現方法。設計模式就是實現了這些原則,從而達到了代碼複用、增加可維護性的目的。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

簡單工廠模式  

主要用於創建對象。新添加類時,不會影響以前的系統代碼。核心思想是用一個工廠來根據輸入的條件產生不同的類,然後根據不同類的virtual函數得到不同的結果。

  GOOD:適用於不同情況創建不同的類時

BUG:客戶端必須要知道基類和工廠類,耦合性差

(工廠類與基類爲關聯關係

例:

//基類

class COperation

{

public:

       int m_nFirst;

       int m_nSecond;

       virtual double GetResult()

       {

              double dResult=0;

              return dResult;

       }

};

//加法

classAddOperation : public COperation

{

public:

       virtual double GetResult()

       {

              return m_nFirst+m_nSecond;

       }

};

//減法

classSubOperation : public COperation

{

public:

       virtual double GetResult()

       {

              return m_nFirst-m_nSecond;

       }

};

 

//工廠類

class CCalculatorFactory

{

public:

       staticCOperation* Create(char cOperator);

};

COperation* CCalculatorFactory::Create(char cOperator)

{

       COperation *oper;

    //在C#中可以用反射來取消判斷時用的switch,在C++中用什麼呢?RTTI??

       switch (cOperator)

       {

       case '+':

              oper=newAddOperation();

              break;

       case '-':

              oper=newSubOperation();

              break;

       default:

              oper=newAddOperation();

              break;

       }

       return oper;

}

客戶端

int main()

{

       int a,b;

       cin>>a>>b;

       COperation *op=CCalculatorFactory::Create('-');

       op->m_nFirst=a;

       op->m_nSecond=b;

       cout<<op->GetResult()<<endl;

       return 0;

}

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

策略模式

  定義算法家族,分別封裝起來,讓它們之間可以互相替換,讓算法變化,不會影響到用戶

  GOOD:適合類中的成員以方法爲主,算法經常變動;簡化了單元測試(因爲每個算法都有自己的類,可以通過自己的接口單獨測試。

  策略模式和簡單工廠基本相同,但簡單工廠模式只能解決對象創建問題,對於經常變動的算法應使用策略模式。

  BUG:客戶端要做出判斷

//策略基類

class COperation

{

public:

       int m_nFirst;

       int m_nSecond;

       virtual double GetResult()

       {

              double dResult=0;

              return dResult;

       }

};

 

//策略具體類—加法類

classAddOperation : public COperation

{

public:

       AddOperation(int a,int b)

       {

              m_nFirst=a;

              m_nSecond=b;

       }

       virtual double GetResult()

       {

              return m_nFirst+m_nSecond;

       }

};

 

class Context

{

private:

       COperation* op;

public:

    Context(COperation*temp)

       {

        op=temp;

       }

       doubleGetResult()

       {

              returnop->GetResult();

       }

};

 

//客戶端

int main()

{

       int a,b;

    char c;

       cin>>a>>b;

  cout<<”請輸入運算符:;

    cin>>c;

    switch(c)

{

   case ‘+’:

      Context *context=newContext(new AddOperation(a,b));

    cout<<context->GetResult()<<endl;

    break;

   default:

    break;

}

       return 0;

}

策略與工廠結合

GOOD:客戶端只需訪問Context類,而不用知道其它任何類信息,實現了低耦合。

在上例基礎上,修改下面內容

class Context

{

private:

       COperation* op;

public:

    Context(charcType)

       {

        switch (cType)

        {

              case '+':

                     op=newAddOperation(3,8);

                     break;

              default:

                     op=newAddOperation();

                     break;

        }

       }

       double GetResult()

       {

              return op->GetResult();

       }

};

//客戶端

int main()

{

       int a,b;

       cin>>a>>b;

       Context *test=newContext('+');

       cout<<test->GetResult()<<endl;

       return 0;

}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

裝飾模式

動態地給一個對象添加一些額外的職責(不重要的功能,只是偶然一次要執行),就增加功能來說,裝飾模式比生成子類更爲靈活。建造過程不穩定,按正確的順序串聯起來進行控制

GOOD:當你向舊的類中添加新代碼時,一般是爲了添加核心職責或主要行爲。而當需要加入的僅僅是一些特定情況下才會執行的特定的功能時(簡單點就是不是核心應用的功能),就會增加類的複雜度。裝飾模式就是把要添加的附加功能分別放在單獨的類中,並讓這個類包含它要裝飾的對象,當需要執行時,客戶端就可以有選擇地、按順序地使用裝飾功能包裝對象。

#include<string>

#include<iostream>

using namespacestd;

//人

class Person

{

private:

       string m_strName;

public:

       Person(string strName)

       {

              m_strName=strName;

       }

       Person(){}

       virtual void Show()

       {

              cout<<"裝扮的是:"<<m_strName<<endl;

       }

 

};

//裝飾類

class Finery :public Person

{

protected:

       Person*m_component;

public:

       voidDecorate(Person* component)

       {

              m_component=component;

       }

       virtual voidShow()

       {

                 m_component->Show();

       }

};

//T恤

class TShirts:public Finery

{

public:

       virtual void Show()

       {

              cout<<"TShirts"<<endl;

              m_component->Show();

       }

};

//褲子

class BigTrouser:public  Finery

{

public:

       virtual void Show()

       {

              cout<<" BigTrouser"<<endl;

              m_component->Show();

       }

};

 

//客戶端

int main()

{

       Person *p=new Person("小李");

       BigTrouser *bt=new BigTrouser();

       TShirts *ts=new TShirts();

 

       bt->Decorate(p);

       ts->Decorate(bt);

       ts->Show();

       return 0;

}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

代理模式

   GOOD:遠程代理,可以隱藏一個對象在不同地址空間的事實

       虛擬代理:通過代理來存放需要很長時間實例化的對象

       安全代理:用來控制真實對象的訪問權限

       智能引用:當調用真實對象時,代理處理另外一些事

#include<string>

#include<iostream>

using namespacestd;

//定義接口

class Interface

{

public:

       virtual void Request()=0;

};

//真實類

class RealClass: public Interface

{

public:

       virtual void Request()

       {

              cout<<"真實的請求"<<endl;

       }

};

//代理類

class ProxyClass: public Interface

{

private:

       RealClass* m_realClass;

public:

       virtual void Request()

       {

          m_realClass= new RealClass();

              m_realClass->Request();

              delete m_realClass;

       }

};

 

客戶端:

int main()

{

       ProxyClass* test=new ProxyClass();

       test->Request();

       return 0;

}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

工廠方法模式

   GOOD:修正了簡單工廠模式中不遵守開放-封閉原則。工廠方法模式把選擇判斷移到了客戶端去實現,如果想添加新功能就不用修改原來的類,直接修改客戶端即可。

#include<string>

#include<iostream>

using namespacestd;

//實例基類,相當於Product(爲了方便,沒用抽象)

class LeiFeng

{

public:

       virtual void Sweep()

       {

              cout<<"雷鋒掃地"<<endl;

       }

};

 

//學雷鋒的大學生,相當於ConcreteProduct

class Student:public LeiFeng

{

public:

       virtual void Sweep()

       {

              cout<<"大學生掃地"<<endl;

       }

};

 

//學雷鋒的志願者,相當於ConcreteProduct

class Volenter:public LeiFeng

{

public :

       virtual void Sweep()

       {

              cout<<"志願者"<<endl;

       }

};

//工場基類Creator

class LeiFengFactory

{

public:

       virtual LeiFeng*CreateLeiFeng()

       {

              return newLeiFeng();

       }

};

//工場具體類

class StudentFactory : public LeiFengFactory

{

public :

       virtual LeiFeng*CreateLeiFeng()

       {

              return newStudent();

       }

};

class VolenterFactory : public LeiFengFactory

{

public:

       virtual LeiFeng*CreateLeiFeng()

       {

              return newVolenter();

       }

};

//客戶端

int main()

{

       LeiFengFactory *sf=new StudentFactory ();

       LeiFeng *s=sf->CreateLeiFeng();

       s->Sweep();

       delete s;

       delete sf;

       return 0;

}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

原型模式

   GOOD:從一個對象再創建另外一個可定製的對象,而無需知道任何創建的細節。並能提高創建的性能。說白了就COPY技術,把一個對象完整的COPY出一份。

#include<iostream>

#include<vector>

#include<string>

using namespacestd;

 

class Prototype//抽象基類

{

private:

       string m_strName;

public:

       Prototype(string strName){ m_strName =strName; }

       Prototype() { m_strName = " ";}

       void Show()

       {

              cout<<m_strName<<endl;

       }

       virtualPrototype* Clone() = 0 ;

} ;

 

// classConcretePrototype1

classConcretePrototype1 : public Prototype

{

public:

       ConcretePrototype1(string strName) :Prototype(strName){}

       ConcretePrototype1(){}

 

       virtualPrototype* Clone()

       {

              ConcretePrototype1*p = new ConcretePrototype1() ;

              *p = *this; //複製對象

              return p ;

       }

} ;

 

// classConcretePrototype2

classConcretePrototype2 : public Prototype

{

public:

       ConcretePrototype2(string strName) :Prototype(strName){}

       ConcretePrototype2(){}

 

       virtual Prototype* Clone()

       {

              ConcretePrototype2 *p = newConcretePrototype2() ;

              *p = *this ; //複製對象

              return p ;

       }

} ;

 

//客戶端

int main()

{

       ConcretePrototype1* test = newConcretePrototype1("小王");

       ConcretePrototype2*test2 = (ConcretePrototype2*)test->Clone();

       test->Show();

       test2->Show();

       return 0;

}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章