C++

设计模式

C++设计模式

Posted by Bob on January 12, 2019

GoF(“四人帮”,指Gamma, Helm, Johnson & Vlissides, Addison-Wesley四人)提出的23种设计模式。

通过分解和抽象来管理变化,提高复用。

八大原则:

  • 依赖倒置原则 DIP(Dependency Inversion Principle):一个方法应该遵从”依赖于抽象而不是一个实例”。

  • 开放封闭原则 OCP(Open/Closed Principle):软件体应该是对于扩展开放的,但是对于修改封闭的。

  • 单一职责 SRP(Single Responsibility Principle):对象应该仅具有一种单一功能。

  • Liskov 替换原则 LSP(Liskov Substitution Principle):程序中的对象应该是可以在不改变程序正确性的前提下被它的子类所替换的。

  • 接口隔离原则 ISP(Interface Segregation Principle):多个特定客户端接口要好于一个宽泛用途的接口。

  • 对象组合优于类集成

  • 封装变化点

  • 面向接口编程

———-默认三大类别———-

Creational

FACTORY、BUILDER、PROTOTYPE、SINGLETON

Structural

ADAPTER、DECORATOR、BRIDGE、COMPOSITE、FACADE、FLYWEIGHT、PROXY

Behavioral

CHAIN OF RESPONSIBLEITY、COMMAND、INTERPRETER、ITERATOR、MEDIATOR、MEMENTO、OBSERVER、STATE、STRATEGY、TEMPLATE METHOD、VISITOR

———-更细粒度类别———-

下面代码仅仅说明设计模式,不考虑编写规范、内存管理、能否运行、语法正确性等。

组件协作

Template Method

class SoundLibrary{
public:
    void Load(){};
    void Decode(){};
    void Play(){};
};

class MusicPlayer{
public:
    void Analyse(){};
    void Output(){};
};

int main(int argc, const char * argv[]) {
    SoundLibrary lib;
    MusicPlayer player;
    
    lib.Load();
    player.Analyse();
    lib.Decode();
    player.Output();
    lib.Play();
    
    return 0;
}

Template Method模式——在父类中定义一个操作中的算法的骨架(稳定的),而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义(override)该算法的某些特定步骤(变化的)。

#include <iostream>

class SoundLibrary{
public:
    //Tempalte method (稳定的)

    void Run(){
        this->Load();
        this->Analyse();
        this->Decode();
        this->Output();
        this->Play();
    }
    virtual ~SoundLibrary(){};
protected:
    void Load(){};
    void Decode(){};
    void Play(){};
    virtual void Analyse() = 0;//Change

    virtual void Output() = 0;//Change
};

class MusicPlayer:public SoundLibrary{
protected:
    virtual void Analyse(){std:std::cout<<"Analyse"<<std::endl;};//Subclass Implementation

    virtual void Output(){std:std::cout<<"Output"<<std::endl;};//Subclass Implementation

};

int main(int argc, const char * argv[]) {
    SoundLibrary* lib = new MusicPlayer();
    lib->Run();
    delete lib;
    return 0;
}
Strategy
enum PlatformType{
    PC,
    ANDROID,
    IOS,
    PS4
};

class ShopItem{
    PlatformType type;
public:
    
    long CalcPrice(){
        if (type == PC) {
            
        } else if(type == ANDROID) {
            
        } else if(type == IOS) {
            
        } else if(type == PS4) {
            
        }
        return 0;
    }
    
};

Strategy 策略模式——定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换(变化的)。本模式使得算法的变化可独立于使用它的程序(稳定的)。

#include <iostream>

enum PlatformType{
    PC,
    ANDROID,
    IOS,
    PS4
};


class PriceStrategy{
public:
    virtual long CalcPrice()=0;
    virtual ~PriceStrategy(){};
};


class PcStrategy:public PriceStrategy{
public:
    virtual long CalcPrice(){
        //do something

        return 1;
    };
};

class AndroidStrategy:public PriceStrategy{
public:
    virtual long CalcPrice(){
        //do something

        return 2;
    };
};

class IosStrategy:public PriceStrategy{
public:
    virtual long CalcPrice(){
        //do something

        return 3;
    };
};

class Ps4Strategy:public PriceStrategy{
public:
    virtual long CalcPrice(){
        //do something

        return 4;
    };
};

//稳定不变的

class ShopItem{
private:
    PriceStrategy* m_strategy;
public:
    ShopItem(PriceStrategy* strategy):m_strategy(strategy){
       
    };
    
    void ShowView(){
        //do something;

        double price = m_strategy->CalcPrice();
        std::cout << price << std::endl;
        //do something;

    };
    
    ~ShopItem(){
        delete this->m_strategy;
    };
};
Observer/Event
#include <iostream>

class ProgressBar{
public:
    void UpdateView(float progress){};
};

class FileLoad{
    std::string m_filePath;
    ProgressBar* m_bar;//依赖不好.如果换一种界面更新方式?

public:
    FileLoad(const std::string& filePath,ProgressBar* bar):m_filePath(filePath),m_bar(bar){
    }
    void Load(){
        //load file

        //.....

        if(m_bar != nullptr){
            m_bar->UpdateView(100);
        }
    };
};


class Panel{
    ProgressBar* m_bar;
public:
    void ButtonClick(){
        std::string filePath = "bob.mp3";
        FileLoad fl(filePath,m_bar);
        fl.Load();
    };
};

Observer 观察者模式:定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。


#include <iostream>
#include <vector>


class IListenter {
public:
    IListenter(){std::cout<< "IListenter" << std::endl;};
    virtual ~IListenter(){std::cout<< "~IListenter" << std::endl;};
    IListenter(const IListenter& other){std::cout<< "Copy" << std::endl;}
    virtual void OnProgress(float progress) = 0;
    
};


class IDispatch{
private:
    std::vector<IListenter*> listenters;
public:
    
    void AddListenter(IListenter* listener){
        listenters.push_back(listener);
    }
    void Dispatch(float data){
        for (IListenter* listener : listenters)
            listener->OnProgress(data);
    };
};


class FileLoad:public IDispatch{
    std::string m_filePath;
public:
    FileLoad(const std::string& filePath):m_filePath(filePath){
    }
    void Load(){
        this->Dispatch(100);
    };
};



class ProgressBar:public IListenter{
public:
    void UpdateView(float progress){};
    
    virtual void OnProgress(float progress){
        UpdateView(progress);
    };
};


class Panel{
    ProgressBar* m_bar;
public:
    Panel(){
        m_bar = new ProgressBar();
    }
    void ButtonClick(){
        std::string filePath = "bob.mp3";
        FileLoad fl(filePath);
        fl.AddListenter(m_bar);
        fl.Load();
    };
};


int main(int argc, const char * argv[]) {
    Panel* panel = new Panel();
    panel->ButtonClick();
    return 0;
}

单一职责

Decorator
#include <iostream>

class Stream{
public:
    virtual char Read(int number) = 0;
    virtual void Seek(int position) = 0;
    virtual void Write(char data) = 0;
    
    virtual ~Stream(){};
};

class FileStream:public Stream{
public:
    virtual char Read(int number){ return '\n';};
    virtual void Seek(int position){};
    virtual void Write(char data){};
};

class NetWorkStream:public Stream{
public:
    virtual char Read(int number){ return '\n';};
    virtual void Seek(int position){};
    virtual void Write(char data){};
};

class MemoryStream:public Stream{
public:
    virtual char Read(int number){ return '\n';};
    virtual void Seek(int position){};
    virtual void Write(char data){};
};

class CryptoFileStream:public FileStream{
public:
    virtual char Read(int number){
        //do something

        return FileStream::Read(number);
    };
    virtual void Seek(int position){
        //do something

        FileStream::Seek(position);
    };
    virtual void Write(char data){
        //do something

        FileStream::Write(data);
    };
};

class BufferFileStream:public FileStream{
public:
    virtual char Read(int number){
        //do something

        return FileStream::Read(number);
    };
    virtual void Seek(int position){
        //do something

        FileStream::Seek(position);
    };
    virtual void Write(char data){
        //do something

        FileStream::Write(data);
    };
};

class CryptoNetWorkStream:public NetWorkStream{
public:
    virtual char Read(int number){
        //do something

        return NetWorkStream::Read(number);
    };
    virtual void Seek(int position){
        //do something

        NetWorkStream::Seek(position);
    };
    virtual void Write(char data){
        //do something

        NetWorkStream::Write(data);
    };
};

//Class BufferNetWorkStream....

class CryptoMemoryStream:public MemoryStream{
public:
    virtual char Read(int number){
        //do something

        return MemoryStream::Read(number);
    };
    virtual void Seek(int position){
        //do something

        MemoryStream::Seek(position);
    };
    virtual void Write(char data){
        //do something

        MemoryStream::Write(data);
    };
};

//Class BufferMemoryStream....

Decorator 装饰模式——动态地给一个对象添加一些额外的职责。就扩展功能而言,Decorator模式比生成子类方式更为灵活。


//用组合来扩展变化的部分 ,避免继承带来的灵活性差和多子类衍生问题

class DecoratorStream:public Stream{
protected:
  Stream* m_stream;//FileStream....

  DecoratorStream(Stream*stream):m_stream(stream){};
};

class CryptoStream:public DecoratorStream{
public:
    CryptoStream(Stream*stream):DecoratorStream(stream){};
    virtual char Read(int number){
        //do something

        return m_stream->Read(number);
    };
    virtual void Seek(int position){
        //do something

        m_stream->Seek(position);
    };
    virtual void Write(char data){
        //do something

        m_stream->Write(data);
    };
};

class BufferStream:public DecoratorStream{
public:
    BufferStream(Stream*stream):DecoratorStream(stream){};
    virtual char Read(int number){
        //do something

        return m_stream->Read(number);
    };
    virtual void Seek(int position){
        //do something

        m_stream->Seek(position);
    };
    virtual void Write(char data){
        //do something

        m_stream->Write(data);
    };
};


int main(int argc, const char * argv[]) {
    FileStream* fs = new FileStream();
    CryptoStream* cs = new CryptoStream(fs);
    cs->Seek(10);
    return 0;
}

Bridge
#include <iostream>

using namespace std;

class Message{
public:
    virtual void Login(string userName,string password) = 0;
    virtual void SendMessage(string msg) = 0;
    virtual void SendPic(string path) = 0;
    
    //change
    virtual void PlaySound() = 0;
    virtual void DrawShape() = 0;
    virtual void WriteText() = 0;
    virtual void Connect() = 0;
    
    virtual ~Message(){};
};

class PcMessageBase:public Message{
public:
    virtual void PlaySound(){};
    virtual void DrawShape(){};
    virtual void WriteText(){};
    virtual void Connect(){};
};

class PcMessageLite:public PcMessageBase{
public:
    virtual void Login(string userName,string password){
        PcMessageBase::Connect();
    };
    virtual void SendMessage(string message){
        PcMessageBase::WriteText();
    };
    virtual void SendPic(string path){
        PcMessageBase::DrawShape();
    };
};

class PcMessageUltimate:public PcMessageBase{
public:
    virtual void Login(string userName,string password){
        PcMessageBase::PlaySound();
        PcMessageBase::Connect();
    };
    virtual void SendMessage(string message){
        PcMessageBase::PlaySound();
        PcMessageBase::WriteText();
    };
    virtual void SendPic(string path){
        PcMessageBase::PlaySound();
        PcMessageBase::DrawShape();
    };
};

//MoblieMessageBase
//MoblieMessageLite
//MoblieMessageUltimate

Bridge 桥接模式——将抽象部分与它的实现部分分离,使它们都可以独立地变化。


#include <iostream>

using namespace std;

class PlatformMessage{
public:
    virtual void PlaySound() = 0;
    virtual void DrawShape() = 0;
    virtual void WriteText() = 0;
    virtual void Connect() = 0;
};

class Message{
protected:
    PlatformMessage* m_message;
public:
    Message(PlatformMessage* message):m_message(message){};
    virtual void Login(string userName,string password) = 0;
    virtual void SendMessage(string msg) = 0;
    virtual void SendPic(string path) = 0;
    
    virtual ~Message(){};
};


class PcMessageBase:public PlatformMessage{
public:
    virtual void PlaySound(){};
    virtual void DrawShape(){};
    virtual void WriteText(){};
    virtual void Connect(){};
};

class MobileMessageBase:public PlatformMessage{
public:
    virtual void PlaySound(){};
    virtual void DrawShape(){};
    virtual void WriteText(){};
    virtual void Connect(){};
};

class MessageLite:public Message{
public:
    MessageLite(PlatformMessage* message):Message(message){};
    virtual void Login(string userName,string password){
        m_message->Connect();
    };
    virtual void SendMessage(string msg){
        m_message->WriteText();
    };
    virtual void SendPic(string path){
        m_message->DrawShape();
    };
};

class MessageUltimate:public Message{
public:
    MessageUltimate(PlatformMessage* message):Message(message){};
    virtual void Login(string userName,string password){
        m_message->PlaySound();
        m_message->Connect();
    };
    virtual void SendMessage(string msg){
        m_message->PlaySound();
        m_message->WriteText();
    };
    virtual void SendPic(string path){
        m_message->PlaySound();
        m_message->DrawShape();
    };
};

对象创建

Factory Method
#include <iostream>

using namespace std;

class ILoad{
public:
    virtual void Load() = 0;
    virtual ~ILoad(){};
};

class PngLoad:public ILoad{
    virtual void Load(){};
};

class EtcLoad:public ILoad{
    virtual void Load(){};
};

class AstcLoad:public ILoad{
    virtual void Load(){};
};

class Panel{
public:
    void ButtonClick(){
        ILoad* il = new PngLoad();//依赖具体类

        il->Load();
    };
};

Factory Method 工厂方法模式——定义一个用于创建对象的接口,让子类决定将哪一个类实例化。Factory Method使一个类的实例化延迟到其子类。

class LoadFactory{
public:
    virtual ILoad* CreateLoad() = 0;
    virtual ~LoadFactory(){};
};

//变化的

class PngLoadFactory:public LoadFactory{
public:
    virtual ILoad* CreateLoad(){
        return new PngLoad();
    };
};

class EtcLoadFacotry:public LoadFactory{
public:
    virtual ILoad* CreateLoad(){
        return new EtcLoad();
    };
};

//稳定的

class Panel{
    LoadFactory* m_Factory;
public:
    Panel(LoadFactory* Factory):m_Factory(Factory){};
    void ButtonClick(){
        ILoad* il = m_Factory->CreateLoad();
        il->Load();
    };
};
Abstract Factory
#include <iostream>
#include <vector>

using namespace std;

//sqlserver

class SqlConnection{};
class SqlCommand{};
class SqlDataReader{};

//Oracle

class OracleConnection{};
class OracleCommand{};
class OracleDataReader{};

//MySQL

class MySqlConnection{};
class MySqlCommand{};
class MySqlDataReader{};

//如果换种数据库?

class CardDAO{
public:
    vector<CardDAO> GetCards()
    {
        SqlConnection* connection = new SqlConnection();
        //do something;

        SqlCommand* command = new SqlCommand();
        //do something;

        SqlDataReader* reader =new SqlDataReader();
        //do something;

        vector<CardDAO> vct;
        return vct;
    };
};

Abstract Factory 抽像工厂模式——提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

#include <iostream>
#include <vector>

using namespace std;

class IConnection{};
class ICommand{};
class IDataReader{};

//sqlserver

class SqlConnection:public IConnection{};
class SqlCommand:public ICommand{};
class SqlDataReader:public IDataReader{};


//Oracle

class OracleConnection:public IConnection{};
class OracleCommand:public ICommand{};
class OracleDataReader:public IDataReader{};

//MySQL

class MySqlConnection:public IConnection{};
class MySqlCommand:public ICommand{};
class MySqlDataReader:public IDataReader{};

class IFactory{
public:
    virtual IConnection* CreateConnection() = 0;
    virtual ICommand* CreateCommand() = 0;
    virtual IDataReader* CreateReader() = 0;
};

class SqlFactory:public IFactory{
public:
    virtual IConnection* CreateConnection(){
        return new SqlConnection();
    };
    virtual ICommand* CreateCommand(){
        return new SqlCommand();
    };

    virtual IDataReader* CreateReader(){
        return new SqlDataReader();
    };

};

class CardDAO{
    IFactory* m_factory;
public:
    CardDAO(IFactory* factory):m_factory(factory){}
    vector<CardDAO> GetCards(){
        IConnection* connection = m_factory->CreateConnection();
        ICommand* command = m_factory->CreateCommand();
        IDataReader* reader = m_factory->CreateReader();
        //do something

        vector<CardDAO> vct;
        return vct;
    };
};

Prototype
#include <iostream>
#include <vector>

using namespace std;

class ILoad{
public:
    virtual void Load() = 0;
    virtual ~ILoad(){};
};

class PngLoad:public ILoad{
    virtual void Load(){};
};

class LoadFactory{
public:
    virtual ILoad* CreateLoad() = 0;
    virtual ~LoadFactory(){};
};

class PngLoadFactory:public LoadFactory{
public:
    virtual ILoad* CreateLoad(){
        return new PngLoad();
    };
};

class Panel{
    LoadFactory* m_Factory;
public:
    Panel(LoadFactory* Factory):m_Factory(Factory){};
    void ButtonClick(){
        ILoad* il = m_Factory->CreateLoad();
        il->Load();
    };
};

Prototype 原型模式——用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象。


#include <iostream>
#include <vector>

using namespace std;

class ILoad{
public:
    virtual void Load() = 0;
    virtual ILoad* Clone() = 0;
    virtual ~ILoad(){};
};

class PngLoad:public ILoad{
    virtual void Load(){};
    virtual ILoad* Clone(){
        return new PngLoad(*this);
    };
};

class Panel{
    ILoad* m_prototype;
public:
    Panel(ILoad* prototype):m_prototype(prototype){};
    void ButtonClick(){
        ILoad* il = m_prototype->Clone();
        il->Load();
    };
};

Builder
#include <iostream>
#include <vector>

using namespace std;

class Room{
public:
    void Build(){
        BuildFloor();
        BuildWall();
        BuildRoof();
    };
    virtual ~Room(){};
protected:
    virtual void BuildWall()=0;
    virtual void BuildFloor()=0;
    virtual void BuildRoof()=0;
};

class StoneRoom:public Room{
protected:
    virtual void BuildWall(){};
    virtual void BuildFloor(){};
    virtual void BuildRoof(){};
};

int main(int argc, const char * argv[]) {
    Room* room = new StoneRoom();
    room->Build();
    return 0;
}

Builder 生成器模式——将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

#include <iostream>
#include <vector>

using namespace std;

class Room{};

class RoomBuilder{
public:
    virtual ~RoomBuilder(){};
    
    Room* GetResult(){
        return m_room;
    }
    
public:
    Room* m_room;
    
    virtual void BuildWall()=0;
    virtual void BuildFloor()=0;
    virtual void BuildRoof()=0;
    
};

class StoneRoom:public Room{};

class StoneRoomBuilder:public RoomBuilder{
protected:
    virtual void BuildWall(){};
    virtual void BuildFloor(){};
    virtual void BuildRoof(){};
};

class RoomDirector{
public:
    RoomBuilder* roomBuilder;
public:
    void Build(){
        roomBuilder->BuildFloor();
        roomBuilder->BuildWall();
        roomBuilder->BuildRoof();
        
        roomBuilder->GetResult();
    };
};

对象性能

Singleton

Singleton 单态模式——保证一个类仅有一个实例,并提供一个访问它的全局访问点。

#include <iostream>
#include <vector>

using namespace std;

class Singleton{
private:
    Singleton();
    Singleton(const Singleton& other);
public:
    static Singleton* GetInstance();
    static Singleton* m_instance;
};

Singleton* Singleton::m_instance = nullptr;

//线程非安全的

Singleton* Singleton::GetInstance(){
    if (m_instance == nullptr) {
        m_instance = new Singleton();
    }
    return m_instance;
};
FlyWeight

Flyweight 享元模式——运用共享技术有效地支持大量细粒度的对象。

#include <iostream>
#include <vector>
#include <string>
#include <map>

using namespace std;

class Word{
private:
    string key;
public:
    Word(const string& key){
        
    }
};

class WordFactory{
private:
    map<string,Word*> wordPool;
public:
    Word* GetWord(const string& key){
        map<string,Word*>::iterator item = wordPool.find(key);
        if(item != wordPool.end()){
            return wordPool[key];
        }else{
            Word* word = new Word(key);
            wordPool[key] = word;
            return word;
        }
    };
    
    void Clear(){};
};

接口隔离

Facade

Facade 外观模式——为子系统中的一组接口提供一个一致的界面, Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

#include <iostream>

using namespace std;

class Computer{
public:
    void LoadHardware(){printf("LoadHardware\n");};
    void LoadSystem(){printf("LoadSystem\n");};
    void PlaySound(){printf("PlaySound\n");};
    void Login(){printf("Login\n");};
    void Save(){printf("Save\n");};
    void CloseEverything(){printf("CloseEverything\n");};
};

class ComputerFacade{
    Computer& m_computer;
public:
    ComputerFacade(Computer& computer):m_computer(computer){}

    void TurnOn(){
        m_computer.LoadHardware();
        m_computer.LoadSystem();
        m_computer.PlaySound();
        m_computer.Login();
    };
    
    void TurnOff(){
        m_computer.CloseEverything();
        m_computer.Save();
    }
};

int main(int argc, const char * argv[]) {
    Computer realComputer;
    ComputerFacade computer(realComputer);
    computer.TurnOn();
    computer.TurnOff();
    return 0;
}
Proxy
#include <iostream>

using namespace std;

class IDoor{
public:
    virtual void Open() = 0;
    virtual void Close() = 0;
};

class RealDoor:public IDoor{
public:
    virtual void Open(){
        
    };
    
    virtual void Close(){
    
    };
};


class ClientApp{
    IDoor* door;
public:
    ClientApp(){
        door = new RealDoor();
    };
    void DoTask(){
        door->Open();
    };
};

Proxy 代理模式:为其他对象提供一个代理以控制对这个对象的访问。

#include <iostream>
#include <string>

using namespace std;

class IDoor{
public:
    virtual void Open() = 0;
    virtual void Close() = 0;
};

class RealDoor:public IDoor{
public:
    virtual void Open(){
        
    };
    
    virtual void Close(){
    
    };
};

class Proxy{
    IDoor* m_door;
public:
    Proxy(){
        m_door = new RealDoor();
    };
    bool Check(const string&pwd){
        return pwd == "money";
    };
    void Open(const string&pwd){
        if(Check(pwd)){
            m_door->Open();
        }
    };
    void Close(){
        m_door->Close();
    };
};

class ClientApp{
    Proxy* proxy;
public:
    ClientApp(){
        proxy = new Proxy();
    };
    void DoTask(){
        proxy->Open("money");
    };
};
Mediator

Mediator 中介者模式——用一个中介对象来封装(变化)一系列的对象交互。中介者使各对象不需要显式地相互引用(编译时依赖转运行时依赖),从而使其耦合松散,而且可以独立地改变它们之间的交互。

#include <iostream>
#include <string>

using namespace std;

class View;
class Mediator{
public:
    virtual void Sent(string& msg,View* view) = 0;
};

class View{
protected:
    Mediator* m_pMediator;
public:
    View(Mediator* pMediator):m_pMediator(pMediator){};
    virtual void Send(string& msg) = 0;
};

class MainView:public View{
public:
    MainView(Mediator* pMediator):View(pMediator){};
    void Send(string& msg){
        m_pMediator->Sent(msg,this);
    };
    void Notify(string& msg){};
};


class BattleView:public View{
public:
    BattleView(Mediator* pMediator):View(pMediator){};
    void Send(string& msg){
        m_pMediator->Sent(msg,this);
    };
    void Notify(string& msg){};
};

//View之间不直接沟通,ViewMediator负责所有沟通

class ViewMediator:public Mediator{
private:
    MainView* mainView;
    BattleView* battleView;
public:
    virtual void Sent(string& msg,View* view){
        MainView *mview = dynamic_cast<MainView *>(view);
        if(mview){
            mview->Notify(msg);
        }else{
            if(battleView){
                battleView->Notify(msg);
            }
        }
    };
    
    void SetMainView(MainView* view){mainView = view;}
    void SetBattleView(BattleView* view){battleView = view;}
};
Adapter

Adapter 适配器模式—–将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

#include <iostream>
#include <string>

using namespace std;

//目标接口

class IPlugin{
public:
    virtual void TurnOn() = 0;
    virtual void TurnOff() = 0;
};

//遗留接口

class IAdapter{
public:
    virtual void ShowStatus() = 0;
    virtual void Alarm() = 0;
};


class OldTool:public IAdapter{
public:
    virtual void ShowStatus(){};
    virtual void Alarm(){};
};

class Adapter:public IPlugin{
protected:
    IAdapter* m_adapter;
public:
    Adapter(IAdapter* adapter):m_adapter(adapter){};
    //兼容老接口

    virtual void Process(){
        m_adapter->Alarm();
        m_adapter->ShowStatus();
    };
    virtual void TurnOn(){};
    virtual void TurnOff(){};
};

状态变化

Memento

Memento 备忘模式——在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class Memento{
public :
    int m_width;
    int m_height;
    int m_length;
public:
    
    Memento(int width,int height,int length):
    m_width(width),
    m_height(height),
    m_length(length){};
    
    Memento& operator=(const Memento& mem){
        m_width = mem.m_width;
        m_height = mem.m_height;
        m_length = mem.m_length;
        return *this;
    };
};

class Cube{
private :
    int m_width;
    int m_height;
    int m_length;
public:
    Cube(int width,int attack,int length):
    m_width(width),
    m_height(attack),
    m_length(length){};
    
    Memento Save(){
        Memento mem(m_width,m_height,m_length);
        return mem;
    }
    
    void Load(Memento mem){
        m_width = mem.m_width;
        m_height = mem.m_height;
        m_length = mem.m_length;
    }
    
    void Show() { cout<<"width : "<< m_width<<", height : "<< m_height<<", length : "<< m_length<<endl; }
    void Scale() { m_width -= 10; m_height -= 10;  m_length -= 10; }

};


class Tools
{
public:
    Tools() {}
    void Save(Memento mem) { m_mems.push_back(mem); }
    Memento Load(int state) { return m_mems[state]; }
private:
    vector<Memento> m_mems;
};

int main(int argc, const char * argv[]) {
    Tools tools;
    Cube cube(20,10,9);
    tools.Save(cube.Save()); //保存状态

    cube.Scale();
    cube.Show();
    cube.Load(tools.Load(0)); //载入状态

    cube.Show();
    return 0;
}
State
#include <iostream>
#include <string>

using namespace std;

enum NetWorkState{
    Open,
    Close,
    Connect
};

class NetWorkProcessor{
    NetWorkState state;
public:
    
    void DoTask1(){
        if (state == Open) {
            //do something

            //state = Close;

        }else if(state == Close){
            //do something

            //state = Connect;

        }else if(state == Connect){
            //do something

            //state = Open;

        }
    };
    
    void DoTask2(){
        if (state == Open) {
            state = Connect;
        }else if(state == Close){
            state = Open;
        }else if(state == Connect){
            state = Open;
        }
    };
};

State 状态模式:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。

#include <iostream>
#include <string>

using namespace std;

class NetWorkProcessor;

class NetWorkState{
public:
    virtual void DoTask(NetWorkProcessor *np) = 0;
    virtual ~NetWorkState(){};
};

class NetWorkProcessor{
    NetWorkState* m_curState;
public:
    NetWorkProcessor(NetWorkState *state): m_curState(state){}
    
    void Request(){
        if(m_curState){
            m_curState->DoTask(this);
        }
    }
    
    void ChangeState(NetWorkState* state){
        m_curState = state;
    }
    
    ~NetWorkProcessor() { if(m_curState != 0){delete m_curState;} }
};


class ConnectState:public NetWorkState{
public:
    virtual void DoTask(NetWorkProcessor *np){
        //do something

        //np->ChangeState(OpenState::GetInstance());

    };
};

class CloseState:public NetWorkState{
public:
    virtual void DoTask(NetWorkProcessor *np){
        //do something

        //np->ChangeState(ConnectionState::GetInstance());

    };
};

class OpenState:public NetWorkState{
public:
    virtual void DoTask(NetWorkProcessor *np){
        //do something

        //np->ChangeState(CloseState::GetInstance());

    };
};

数据结构

Composite

Composite 组合模式——–将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得客户对单个对象和复合对象的使用具有一致性。

#include <iostream>
#include <string>
#include <vector>
#include <list>

using namespace std;

class UIWidget{
public:
    virtual void Process() = 0;
    virtual ~UIWidget(){};
};

class Group:public UIWidget{
    string m_name;
    list<UIWidget*> elements;
public:
    Group(const string& name):m_name(name){};
    
    void Add(UIWidget* widget){
        elements.push_back(widget);
    }
    
    void Remove(UIWidget* widget){
        elements.remove(widget);
    }
    
    virtual void Process(){
        for (auto& e:elements) {
            e->Process();
        }
    }
};

class Item:public UIWidget{
    string m_name;
public:
    Item(string name):m_name(name){};
    
    virtual void Process(){
        
    }
};

int main(int argc, const char * argv[]) {
    Group root("uiRoot");
    Group grid1("grid1");
    Group grid2("grid2");
    Group grid3("grid3");
    Item item1("item1");
    Item item2("item2");
    
    root.Add(&grid1);
    grid1.Add(&grid2);
    grid2.Add(&item1);
    
    root.Process();
    
    return 0;
}
Iterator

Iterator 迭代器模式—–提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。

#include <iostream>
#include <string>
#include <vector>
#include <list>

using namespace std;

class Iterator {
public:
    virtual string First() = 0;
    virtual string Next() = 0;
    virtual bool IsEnd() const = 0;
    virtual string GetCurrent() = 0;
};

class MyCollection;

class CollectionIterator:public Iterator{
    MyCollection* mc;
public:
    CollectionIterator(MyCollection* c):mc(c){};
    string First() override{return "frist";};
    string Next() override{return "next";};
    bool IsEnd()const override{return true;};
    string GetCurrent()override{return "current";};
};

class MyCollection{
public:
    Iterator* GetIterator(){
        return new CollectionIterator(this);
    };
};

int main(int argc, const char * argv[]) {
    MyCollection mc;
    Iterator* it = mc.GetIterator();
    for (it->First(); !it->IsEnd(); it->Next()) {
        it->GetCurrent();
    }
    return 0;
}

Chain of Resposibility

Chain of Responsibility 职责链模式——为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。

#include <iostream>
#include <string>
#include <vector>
#include <list>

using namespace std;

class Manager
{
protected:
    Manager *m_manager;
    string m_name;
public:
    Manager(Manager *manager, string name):m_manager(manager), m_name(name){}
    virtual void DealWithRequest(string name, int money)  {}
};


class Leader:public Manager{
public:
    Leader(Manager *manager, string name):Manager(manager,name){}
    void DealWithRequest(string name, int money)  {
        if(money < 500){
            //agree

        }else{
            m_manager->DealWithRequest(name, money);
        }
    };
};

class General:public Manager{
public:
    General(Manager *manager, string name):Manager(manager,name){}
    void DealWithRequest(string name, int money)  {
        if(money < 1500){
            //agree

        }else{
            m_manager->DealWithRequest(name, money);
        }
    };
};

class Boss:public Manager{
public:
    Boss(Manager *manager, string name):Manager(manager,name){}
    void DealWithRequest(string name, int money)  {
        if(money < 5000){
            //agree

        }else{
            m_manager->DealWithRequest(name, money);
        }
    };
};

int main(int argc, const char * argv[]) {
    Manager * boss = new Boss(NULL, "Boss");
    Manager * general = new General(boss, "General");
    Manager * leader = new Leader(general, "Leader");
    boss->DealWithRequest("Connie",300);
    general->DealWithRequest("Jennifer", 600);
    leader->DealWithRequest("Bob", 1000);

    return 0;
}

行为变化

Command

Command 命令模式——将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。

#include <iostream>
#include <string>
#include <vector>
#include <list>

using namespace std;

class Command{
public:
    virtual void Execute() = 0;
};

class MoveCommand:public Command{
    string m_param;
public:
    MoveCommand(const string& param):m_param(param){};
    virtual void Execute(){cout << "Move" << endl;}
};

class StandCommand:public Command{
    string m_param;
public:
    StandCommand(const string& param):m_param(param){};
    virtual void Execute(){cout << "Stand" << endl;}
};

class Action:public Command{
    vector<Command*> commands;
public:
    void addCommand(Command* c){commands.push_back(c);};
    void Execute(){
        for(auto &c:commands){
            c->Execute();
        }
    }
};

int main(int argc, const char * argv[]) {
    MoveCommand c1("forward");
    StandCommand c2("speak");
    
    Action action;
    action.addCommand(&c1);
    action.addCommand(&c2);
    action.Execute();

    return 0;
}

Visitor
#include <iostream>
#include <string>
#include <vector>
#include <list>

using namespace std;

class Element{
public:
    virtual void Draw() = 0;
    //virtual void Clear() = 0; //需要扩展的接口

    virtual ~Element(){};
};

class Rectangle:public Element{
public:
    virtual void Draw(){
    
    }
    //virtual void Clear(){}

};

class Circle:public Element{
public:
    virtual void Draw(){
        
    }
    //virtual void Clear(){}
    
};

Visitor 访问者模式—–表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

#include <iostream>
#include <string>
#include <vector>
#include <list>

using namespace std;

class Visitor;
class Rectangle;
class Circle;

class Element{
public:
    virtual void Accept(Visitor& visitor) = 0;
    virtual ~Element(){};
};

class Visitor{
public:
    virtual void VisitorRect(Rectangle& e) = 0;
    virtual void VisitorCirlce(Circle& e) = 0;
    virtual ~Visitor(){};
};

class Rectangle:public Element{
public:
    virtual void Accept(Visitor& visitor){
        visitor.VisitorRect(*this);
    }
};

class Circle:public Element{
public:
    virtual void Accept(Visitor& visitor){
        visitor.VisitorCirlce(*this);
    }
};

//扩展1

class Handler1:public Visitor{
public:
    virtual void VisitorRect(Rectangle& e){};
    virtual void VisitorCirlce(Circle& e){};
};

//扩展2

class Handler2:public Visitor{
public:
    virtual void VisitorRect(Rectangle& e){};
    virtual void VisitorCirlce(Circle& e){};
};

int main(int argc, const char * argv[]) {
    Handler1 h1;
    Rectangle rect;
    rect.Accept(h1);
    
    Circle circle;
    circle.Accept(h1);
    
    
    return 0;
}

领域问题

Interpreter

Interpreter 解释器模式——给定一个语言, 定义它的文法的一种表示,并定义一个解释器, 该解释器使用该表示来解释语言中的句子。

#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <stack>

using namespace std;

class Expression{
public:
    virtual int Interpreter(map<char,int> var) = 0;
    virtual ~Expression(){};
};

class VarExpression:public Expression{
    char key;
public:
    VarExpression(const char&key){
        this->key = key;
    }
    
    virtual int Interpreter(map<char,int> var){
        return var[key];
    };
};

class SymbolExpression:public Expression{
protected:
    Expression* left;
    Expression* right;
public:
    SymbolExpression(Expression* left,Expression* right):left(left),right(right){};
};

class AddExpression:public SymbolExpression{
public:
    AddExpression(Expression* left,Expression* right):SymbolExpression(left,right){};
    
    virtual int Interpreter(map<char,int> var){
        return left->Interpreter(var) + right->Interpreter(var);
    };
};

class SubExpression:public SymbolExpression{
public:
    SubExpression(Expression* left,Expression* right):SymbolExpression(left,right){};
    
    virtual int Interpreter(map<char,int> var){
        return left->Interpreter(var) - right->Interpreter(var);
    };
};

Expression* Analyse(string expStr){
    stack<Expression*> expStack;
    Expression* left = nullptr;
    Expression* right = nullptr;
    for (int i = 0; i < expStr.size(); i++) {
        switch (expStr[i]) {
            case '+':
                left = expStack.top();
                right = new VarExpression(expStr[++i]);
                expStack.push(new AddExpression(left,right));
                break;
            case '-':
                left = expStack.top();
                right = new VarExpression(expStr[++i]);
                expStack.push(new SubExpression(left,right));
                break;
            default:
                expStack.push(new VarExpression(expStr[i]));
                break;
        }
    }
    Expression* exp = expStack.top();
    return exp;
};

int main(int argc, const char * argv[]) {
    string expStr = "a+b-c+d";
    map<char,int> var;
    var.insert(make_pair('a',1));
    var.insert(make_pair('b',9));
    var.insert(make_pair('c',8));
    var.insert(make_pair('d',4));
    
    Expression* exp = Analyse(expStr);
    int result = exp->Interpreter(var);
    cout << result << endl;
    
    return 0;
}