常见设计模式

设计模式概述及常见设计模式

一,设计模式目的

高内聚,低耦合

​ 提高代码的复用性,将变化和稳定隔离开

二,设计模式原则

1,八大原则

  • 依赖倒置原则
  • 开放封闭原则
  • 单一职责原则
  • 替换原则
  • 接口隔离原则
  • 优先使用组合而不是继承
  • 封装变化点
  • 针对接口编程

2,依赖倒置原则

变化的代码应该依赖稳定的代码,具体的代码应该依赖抽象的代码

3,开放封闭原则

源代码应该做到对扩展开放,对改变封闭

4,单一职责原则

类的职责应该划分清楚,单一且明确

5,替换原则

子类可以替换掉父类的作用

6,接口隔离原则

提供的接口应当简洁完整,避免累赘

7,优先使用组合而不是继承

组合优于继承,更加灵活,耦合度更低

8,封装变化点

将变化隔离,使得一个类的变化不会影响到其他的类

9,针对接口编程

针对接口之间的标准化调用编程

三,单例模式

1,业务场景

​ 当某个类要求保证全局只有一个对象

2,代码实现

//singleton模式(单例模式)
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;
}






//线程安全版本,但锁的代价过高
Singleton* Singleton::getInstance() {
    Lock lock;
    if (m_instance == nullptr) {
        m_instance = new Singleton();
    }
    return m_instance;
}









//双检查锁,但由于内存读写reorder不安全
Singleton* Singleton::getInstance() {
    
    if(m_instance==nullptr){
        Lock lock;
        if (m_instance == nullptr) {
            m_instance = new Singleton();
        }
    }
    return m_instance;
}








//C++ 11版本之后的跨平台实现 (volatile)
std::atomic<Singleton*> Singleton::m_instance;
std::mutex Singleton::m_mutex;

Singleton* Singleton::getInstance() {
    Singleton* tmp = m_instance.load(std::memory_order_relaxed);
    std::atomic_thread_fence(std::memory_order_acquire);//获取内存fence
    if (tmp == nullptr) {
        std::lock_guard<std::mutex> lock(m_mutex);
        tmp = m_instance.load(std::memory_order_relaxed);
        if (tmp == nullptr) {
            tmp = new Singleton;
            std::atomic_thread_fence(std::memory_order_release);//释放内存fence
            m_instance.store(tmp, std::memory_order_relaxed);
        }
    }
    return tmp;
}

四,观察者模式

1,业务场景

​ 当一个类发生变化时,其他与之相关联的一系列类也要做出反应,例如qt里的信号和槽

2,代码实现

//observer模式(观察者模式)
class observer{
public:
    virtual void response(void) = 0;
    virtual ~observer(){};
};
class subject{
public:
    vector<observer*>observers;
    virtual void add(observer* observer){
        observers.push_back(observer);
    }
    virtual void del(){
        observers.erase(observers.begin());
    }
    virtual void notifyOfAll(void)=0;
    virtual ~subject(){};
};
class concreteSubject:public subject{
public:
    virtual void notifyOfAll(void){
        cout<<"subject 自身状态开始变化"<<endl;
        cout<<endl;
        for(auto obs:observers){
            obs->response();
        }
    }
};
class observer1: public observer{
public:
    virtual void response(void){
        cout<<"observer1 is already"<<endl;
    }
};
class observer2: public observer{
public:
    virtual void response(void){
        cout<<"observer2 is already"<<endl;
    }
};

五,代理模式

1,业务场景

​ 由于安全,性能,或者分布式等原因考虑的时候,一个类无法直接访问另外一个类,需要间接代理

2,代码实现

//proxy模式(代理模式)
class ISubject{
public:
    virtual void process(void)=0;
    virtual ~ISubject(){};
};
class subject{
public:
    subject(void){
        cout<<"subject 访问成功"<<endl;
    }
};
class proxySubject:public ISubject{
public:
    subject* mSubject;
    virtual void process(void){
        mSubject = new subject;
    }
};
class client{
protected:
ISubject* mSubject;
public:
    void process(void){
        mSubject = new proxySubject;
        mSubject -> process();
    }
};
int main(){
    client c;
    c.process();
    return 0;
}

六,策略模式

1,业务场景

​ 当一个类的算法复杂且容易变化时,将算法单独封装和类本身解耦合常用于消除if else语句

2,代码实现

//strategy模式(策略模式)
class TaxStrategy{
public:
    virtual double Calculate()=0;
    virtual ~TaxStrategy(){}
};


class CNTax : public TaxStrategy{
public:
    virtual double Calculate(){
        cout<<"这是 CNTax"<<endl;
    }
};

class USTax : public TaxStrategy{
public:
    virtual double Calculate(){
        cout<<"这是 USTax"<<endl;
    }
};

class DETax : public TaxStrategy{
public:
    virtual double Calculate(){
        cout<<"这是 DETax"<<endl;
    }
};




class FRTax : public TaxStrategy{
public:
	virtual double Calculate(){
		cout<<"这是 FRTax"<<endl;
	}
};


class SalesOrder{
private:
    TaxStrategy* mTaxStrategy;
public:
    SalesOrder(TaxStrategy* TaxStrategy):mTaxStrategy(TaxStrategy){

    }
    ~SalesOrder(){
    }

    void CalculateTax(){
        mTaxStrategy->Calculate(); 
    }
    
};
int main(){
    TaxStrategy* strategy = new CNTax;
    SalesOrder* salesOreder = new SalesOrder(strategy);
    salesOreder -> CalculateTax();
    return 0;
}

七,装饰器模式

1,业务场景

​ 当使用继承的产生的子类数量过于多时,就应该考虑更为灵活的组合来为其动态附着功能

2,代码实现

//decorator模式(装饰器模式)
//业务操作
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){
        //读文件流
    }
    virtual void Seek(int position){
        //定位文件流
    }
    virtual void Write(char data){
        //写文件流
    }

};

class NetworkStream :public Stream{
public:
    virtual char Read(int number){
        //读网络流
    }
    virtual void Seek(int position){
        //定位网络流
    }
    virtual void Write(char data){
        //写网络流
    }
    
};

class MemoryStream :public Stream{
public:
    virtual char Read(int number){
        //读内存流
    }
    virtual void Seek(int position){
        //定位内存流
    }
    virtual void Write(char data){
        //写内存流
    }
    
};

//扩展操作

// 由于两个子类有相同的成员Stream*,所以这个成员要往上提
DecoratorStream: public Stream{
protected:
    Stream* stream;//...
    
    DecoratorStream(Stream * stm):stream(stm){
    
    }
    
};

class CryptoStream: public DecoratorStream {
 

public:
    CryptoStream(Stream* stm):DecoratorStream(stm){
    
    }
    
    
    virtual char Read(int number){
       
        //额外的加密操作...
        stream->Read(number);//读文件流
    }
    virtual void Seek(int position){
        //额外的加密操作...
        stream::Seek(position);//定位文件流
        //额外的加密操作...
    }
    virtual void Write(byte data){
        //额外的加密操作...
        stream::Write(data);//写文件流
        //额外的加密操作...
    }
};



class BufferedStream : public DecoratorStream{
    
    Stream* stream;//...
    
public:
    BufferedStream(Stream* stm):DecoratorStream(stm){
        
    }
    virtual char Read(int number){
       
        //额外的缓存操作...
        stream->Read(number);//读文件流
    }
    virtual void Seek(int position){
        //额外的缓存操作...
        stream::Seek(position);//定位文件流
        //额外的缓存操作...
    }
    virtual void Write(byte data){
        //额外的缓存操作...
        stream::Write(data);//写文件流
        //额外的缓存操作...
    }
};




void Process(){

    //运行时装配
    Stream* s1=new FileStream();
    CryptoStream* s2=new CryptoStream(s1);
    BufferedStream* s3=new BufferedStream(s1);
    BufferedStream* s4=new BufferedStream(s2);
}

八,工厂模式

1,业务场景

​ 当在一个类中new一个另外的对象会导致对该对象依赖,通过工厂模式绕开new,使其依赖于抽象类

2,代码实现

//factory模式(工厂模式)
//抽象类
class ISplitter{
public:
    virtual void split()=0;
    virtual ~ISplitter(){}
};


//工厂基类
class SplitterFactory{
public:
    virtual ISplitter* CreateSplitter()=0;
    virtual ~SplitterFactory(){}
};
//具体类
class BinarySplitter : public ISplitter{
    virtual void split(){

    }
};

class TxtSplitter: public ISplitter{
    virtual void split(){
        
    }
};

class PictureSplitter: public ISplitter{
    virtual void split(){
        
    }
};

class VideoSplitter: public ISplitter{
    virtual void split(){
        
    }
};

//具体工厂
class BinarySplitterFactory: public SplitterFactory{
public:
    virtual ISplitter* CreateSplitter(){
        return new BinarySplitter();
    }
};

class TxtSplitterFactory: public SplitterFactory{
public:
    virtual ISplitter* CreateSplitter(){
        return new TxtSplitter();
    }
};

class PictureSplitterFactory: public SplitterFactory{
public:
    virtual ISplitter* CreateSplitter(){
        return new PictureSplitter();
    }
};

class VideoSplitterFactory: public SplitterFactory{
public:
    virtual ISplitter* CreateSplitter(){
        return new VideoSplitter();
    }
};
class MainForm : public Form
{
    SplitterFactory*  factory;//工厂

public:
    
    MainForm(SplitterFactory*  factory){
        this->factory=factory;
    }
    
	void Button1_Click(){

        
		ISplitter * splitter=
            factory->CreateSplitter(); //多态new
        
        splitter->split();

	}
};

九,抽象工厂模式

1,业务场景

​ 绕开new进行一系列相互依赖的对象的创建

2,代码实现

//abstractFactory模式(抽象工厂模式)
//数据库访问有关的基类
class IDBConnection{
    
};

class IDBCommand{
    
};

class IDataReader{
    
};


class IDBFactory{
public:
    virtual IDBConnection* CreateDBConnection()=0;
    virtual IDBCommand* CreateDBCommand()=0;
    virtual IDataReader* CreateDataReader()=0;
    
};


//支持SQL Server
class SqlConnection: public IDBConnection{
    
};
class SqlCommand: public IDBCommand{
    
};
class SqlDataReader: public IDataReader{
    
};


class SqlDBFactory:public IDBFactory{
public:
    virtual IDBConnection* CreateDBConnection()=0;
    virtual IDBCommand* CreateDBCommand()=0;
    virtual IDataReader* CreateDataReader()=0;
 
};

//支持Oracle
class OracleConnection: public IDBConnection{
    
};

class OracleCommand: public IDBCommand{
    
};

class OracleDataReader: public IDataReader{
    
};



class EmployeeDAO{
    IDBFactory* dbFactory;
    
public:
    vector<EmployeeDO> GetEmployees(){
        IDBConnection* connection =
            dbFactory->CreateDBConnection();
        connection->ConnectionString("...");

        IDBCommand* command =
            dbFactory->CreateDBCommand();
        command->CommandText("...");
        command->SetConnection(connection); //关联性

        IDBDataReader* reader = command->ExecuteReader(); //关联性
        while (reader->Read()){

        }

    }
};

十,命令模式

1,业务场景

​ 需要对行为进行”记录、撤销、事务“时,行为的请求和实现应该松耦合

2,代码实现

//commmand模式(命令模式)
class Command
{
public:
    virtual void execute() = 0;
};

class ConcreteCommand1 : public Command
{
    string arg;
public:
    ConcreteCommand1(const string & a) : arg(a) {}
    void execute() override
    {
        cout<< "#1 process..."<<arg<<endl;
    }
};

class ConcreteCommand2 : public Command
{
    string arg;
public:
    ConcreteCommand2(const string & a) : arg(a) {}
    void execute() override
    {
        cout<< "#2 process..."<<arg<<endl;
    }
};
        
        
class MacroCommand : public Command
{
    vector<Command*> commands;
public:
    void addCommand(Command *c) { commands.push_back(c); }
    void execute() override
    {
        for (auto &c : commands)
        {
            c->execute();
        }
    }
};
        

        
int main()
{

    ConcreteCommand1 command1("Arg ###");
    ConcreteCommand2 command2( "Arg $$$");
    
    MacroCommand macro;
    macro.addCommand(&command1);
    macro.addCommand(&command2);
    
    macro.execute();

}

十一,责任链模式

1,业务场景

​ 一个请求可能被多个对象处理,需要动态的指定接收者

2,代码实现

enum class RequestType
{
    REQ_HANDLER1,
    REQ_HANDLER2,
    REQ_HANDLER3
};

class Reqest
{
    string description;
    RequestType reqType;
public:
    Reqest(const string & desc, RequestType type) : description(desc), reqType(type) {}
    RequestType getReqType() const { return reqType; }
    const string& getDescription() const { return description; }
};

class ChainHandler{
    
    ChainHandler *nextChain;
    void sendReqestToNextHandler(const Reqest & req)
    {
        if (nextChain != nullptr)
            nextChain->handle(req);
    }
protected:
    virtual bool canHandleRequest(const Reqest & req) = 0;
    virtual void processRequest(const Reqest & req) = 0;
public:
    ChainHandler() { nextChain = nullptr; }
    void setNextChain(ChainHandler *next) { nextChain = next; }
    
   
    void handle(const Reqest & req)
    {
        if (canHandleRequest(req))
            processRequest(req);
        else
            sendReqestToNextHandler(req);
    }
};


class Handler1 : public ChainHandler{
protected:
    bool canHandleRequest(const Reqest & req) override
    {
        return req.getReqType() == RequestType::REQ_HANDLER1;
    }
    void processRequest(const Reqest & req) override
    {
        cout << "Handler1 is handle reqest: " << req.getDescription() << endl;
    }
};
        
class Handler2 : public ChainHandler{
protected:
    bool canHandleRequest(const Reqest & req) override
    {
        return req.getReqType() == RequestType::REQ_HANDLER2;
    }
    void processRequest(const Reqest & req) override
    {
        cout << "Handler2 is handle reqest: " << req.getDescription() << endl;
    }
};

class Handler3 : public ChainHandler{
protected:
    bool canHandleRequest(const Reqest & req) override
    {
        return req.getReqType() == RequestType::REQ_HANDLER3;
    }
    void processRequest(const Reqest & req) override
    {
        cout << "Handler3 is handle reqest: " << req.getDescription() << endl;
    }
};

int main(){
    Handler1 h1;
    Handler2 h2;
    Handler3 h3;
    h1.setNextChain(&h2);
    h2.setNextChain(&h3);
    
    Reqest req("process task ... ", RequestType::REQ_HANDLER3);
    h1.handle(req);
    return 0;
}