设计模式C++

C++设计模式

设计模式介绍篇

设计模式的学习要点

  • 理解松耦合设计思想
  • 掌握面向对象设计原则
  • 掌握重构技法改善设计
  • 掌握GOF核心设计模式

深入理解面向对象

向下:深入理解三大面向对象机制

  • 封装,隐藏内部实现
  • 继承,复用现有代码
  • 多态,改写对象行为

向上:深刻把握面向对象机制所带来的抽象意义,理解如何使用这些机制来表达现实世界,掌握什么是“好的面向对象设计”

软件设计固有的复杂性

软件设计复杂的根本原因 —— 变化

  • 客户需求的变化
  • 技术平台的变化
  • 开发团队的变化
  • 市场环境的变化

如何解决复杂性

分解

  • 人们面对复杂性有一个常见的做法:即分而治之,将大问题分解为多个小问题,将复杂问题分解为多个简单问题。

抽象

  • 更高层次来讲,人们处理复杂问题有一个通用的技术,即抽象。由于不能掌握全部的复杂对象,我们选择忽视他的非本质细节,而去泛化和理想化了对象模型。

软件设计的目标

  • 复用

面向对象的设计原则

1) 依赖倒置原则(DIP)

  • 高层模块(稳定)不应该依赖于低层模块(变化),二者都应该依赖于抽象(稳定)。
  • 抽象(稳定)不应该依赖于实现细节(变化),实现细节应该依赖于抽象(稳定)

2) 开放封闭原则(OCP)

  • 对扩展开放,对更改封闭。
  • 类模块应该是可扩展的,但是不可修改。

3) 单一职责原则(SRP)

  • 一个类应该仅有一个引起它变化的原因。
  • 变化的方向隐含着类的责任。

4) Liskov替换原则(LSP)

  • 子类必须能够替换它们的基类(IS-A);
  • 继承表达类型抽象。

5) 接口隔离原则(ISP)

  • 不应该强迫客户程序依赖他们不用的方法;
  • 接口应该小而完备

6) 优先使用对象组合,而不是类继承

  • 类继承通常为“白箱复用”,对象组合通常为“黑箱复用”。
  • 继承在某种程度上破坏了封装性,子类父类耦合度高。
  • 而对象组合则只要求被组合的对象具有良好定义的接口,耦合度低。

7) 封装变化点

  • 使用封装来创建对象之间的分界层,让设计者可以在分界层的一侧进行修改,而不会对另一侧产生不良的影响,从而实现层次间的松耦合。

8)针对接口编程,而不是针对实现编程

  • 不将变量类型声明为某个特定的具体类,而是声明为某个接口;
  • 客户程序无需获知对象的具体类型,只需要知道对象所具有的接口;
  • 减少系统中各个部分的依赖关系,从而实现“高内聚、松耦合”的类型设计方案。

将设计原则提升为设计经验

  • 设计习语

  • 设计模式

  • 架构模式

  • 变化是复用的天敌!

  • 面向对象设计最大的优势在于:抵御变化

重构获得模式 Refactoring to Patterns

  • 1、面向对象设计模式是“好的面向对象设计”,所谓“好的面向对象设计”指是那些可以满足“应对变化,提高复用”的设计。
  • 2、现代软件设计的特征是“需求的频繁变化”。设计模式的要点是“寻找变化点”,然后在变化处应用设计模式,从而来更好的应对需求的变化。“什么时候,什么地点应用设计模式”比“理解设计模式结构本身”更为重要。
  • 3、设计模式的应用不宜先入为主,一上来就使用设计模式是对设计模式的最大误用。没有一步到位的设计模式。敏捷软件开发实践提倡的"Refactoring to Patterns"是目前普遍公认的最好的使用设计模式的方法。

重构关键技法

  • 静态 -> 动态
  • 早绑定 -> 晚绑定
  • 继承 -> 组合
  • 编译时依赖 -> 运行时依赖
  • 紧耦合 -> 松耦合

GOF-23 模式分类

从目的来看

  • 创建型(Creational)模式:将对象的部分创建工作延迟到子类或者其他对象,从而对应需求变化为对象创建时具体类型实现引来从冲击。
  • 结构型模式:通过类继承或者组合获得更灵活的结构,从而应对需求变化为对象的结构带来的冲击。
  • 行为型模式:通过类继承或者对象组合来划分类与对象间的职责,从而应对需求变化为多个交互的对象带来的冲击。

从范围来看

  • 类模式处理类与子类的静态关系
  • 对象模式处理对象间的动态关系。

从封装变化角度对模式分类

1)组件协作

1、现代软件专业分工之后的第一个结果是"框架与应用的划分","组件协助"模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作是常用的模式。
2、典型模式

  • Template Method
  • Observer / Event
  • Strategy

3、动机

  • 在软件构建过程中,对于某一项任务,他常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现。
  • 如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求?
①Template Method
场景
思路
  • 早绑定 ——> 晚绑定
    1、绑定的意思是指定变化点的实现。
    2、从编译时绑定 -> 运行时绑定
DEMO
原型代码(早绑定)
//程序库开发人员
class Library{

public:
	void Step1(){
		//...
	}

    void Step3(){
		//...
    }

    void Step5(){
		//...
    }
};

//应用程序开发人员
class Application{
public:
	bool Step2(){
		//...
    }

    void Step4(){
		//...
    }
};

int main()
{
	Library lib();
	Application app();

	lib.Step1();

	if (app.Step2()){
		lib.Step3();
	}

	for (int i = 0; i < 4; i++){
		app.Step4();
	}

	lib.Step5();

}
(模式)晚绑定
//程序库开发人员
class Library{
public:
	//稳定 template method
    void Run(){
        
        Step1();

        if (Step2()) { //支持变化 ==> 虚函数的多态调用
            Step3(); 
        }

        for (int i = 0; i < 4; i++){
            Step4(); //支持变化 ==> 虚函数的多态调用
        }

        Step5();

    }
	virtual ~Library(){ }

protected:
	
	void Step1() { //稳定
        //.....
    }
	void Step3() {//稳定
        //.....
    }
	void Step5() { //稳定
		//.....
	}

	virtual bool Step2() = 0;//变化
    virtual void Step4() = 0; //变化
};

//应用程序开发人员
class Application : public Library {//多态实现,父类稳定,多态调用
protected:
	virtual bool Step2(){
		//... 子类重写实现
    }

    virtual void Step4() {
		//... 子类重写实现
    }
};
int main()
{
	Library* pLib=new Application();
	lib->Run();
	delete pLib;
	return 0;
}
②Observer / Event 观察者模式
场景
  • 在软件构建过程中,我们需要为某些对象建立一种"通知依赖关系"——一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,将使得软件不能很好的抵御变化。
  • 使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。
思路
demo
(原型)紧耦合
class FileSplitter
{
	string m_filePath;
	int m_fileNumber;
	ProgressBar* m_progressBar;  //与窗口类的对应变量同一个变量
public:
	FileSplitter(const string& filePath, int fileNumber, ProgressBar* progressBar) :
		m_filePath(filePath), 
		m_fileNumber(fileNumber),
		m_progressBar(progressBar){
	}
	void split(){
		//1.读取大文件
		//2.分批次向小文件中写入
		for (int i = 0; i < m_fileNumber; i++){
			//...
			float progressValue = m_fileNumber;
			progressValue = (i + 1) / progressValue;
			m_progressBar->setValue(progressValue);
		}
	}
};

class MainForm : public Form
{
	TextBox* txtFilePath;
	TextBox* txtFileNumber;
	ProgressBar* progressBar;
public:
	void Button1_Click(){
		string filePath = txtFilePath->getText();
		int number = atoi(txtFileNumber->getText().c_str());
		FileSplitter splitter(filePath, number, progressBar); // 两个类之间建立(耦合)关联progressBar
		splitter.split();
	}
};
松耦合(观察者模式)
class IProgress{
public:
	virtual void DoProgress(float value)=0;
	virtual ~IProgress(){}
};
class FileSplitter
{
	string m_filePath;
	int m_fileNumber;
	List<IProgress*>  m_iprogressList; // 抽象通知机制,支持多个观察者
public:
	FileSplitter(const string& filePath, int fileNumber) :
		m_filePath(filePath), 
		m_fileNumber(fileNumber){
	}
	void split(){
		//1.读取大文件
		//2.分批次向小文件中写入
		for (int i = 0; i < m_fileNumber; i++){
			//...
			float progressValue = m_fileNumber;
			progressValue = (i + 1) / progressValue;
			onProgress(progressValue);//发送通知
		}
	}
	void addIProgress(IProgress* iprogress){
		m_iprogressList.push_back(iprogress);
	}
	void removeIProgress(IProgress* iprogress){
		m_iprogressList.remove(iprogress);
	}
protected:
	virtual void onProgress(float value){
		List<IProgress*>::iterator itor=m_iprogressList.begin();
		while (itor != m_iprogressList.end() )
			(*itor)->DoProgress(value); //更新进度条
			itor++;
		}
	}
};
class MainForm : public Form, public IProgress
{
	TextBox* txtFilePath;
	TextBox* txtFileNumber;
	ProgressBar* progressBar;
public:
	void Button1_Click(){
		string filePath = txtFilePath->getText();
		int number = atoi(txtFileNumber->getText().c_str());
		ConsoleNotifier cn;
		FileSplitter splitter(filePath, number);
		splitter.addIProgress(this); //订阅通知
		splitter.addIProgress(&cn)//订阅通知
		splitter.split();
		splitter.removeIProgress(this);
	}

	virtual void DoProgress(float value){
		progressBar->setValue(value);
	}
};

class ConsoleNotifier : public IProgress {
public:
	virtual void DoProgress(float value){
		cout << ".";
	}
};
③Strategy 策略模式
场景
  • 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。
  • 如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?
思路
demo
原型编程()
enum TaxBase {
	CN_Tax,
	US_Tax,
	DE_Tax,
	FR_Tax       //更改
};

class SalesOrder{
    TaxBase tax;
public:
    double CalculateTax(){
        //...
        
        if (tax == CN_Tax){
            //CN***********
        }
        else if (tax == US_Tax){
            //US***********
        }
        else if (tax == DE_Tax){
            //DE***********
        }
		else if (tax == FR_Tax){  //更改
			//...
		}

        //....
     }
    
};
模式(策略模式)
class TaxStrategy{
public:
    virtual double Calculate(const Context& context)=0;
    virtual ~TaxStrategy(){}
};
class CNTax : public TaxStrategy{
public:
    virtual double Calculate(const Context& context){
        //***********
    }
};
class USTax : public TaxStrategy{
public:
    virtual double Calculate(const Context& context){
        //***********
    }
};
class DETax : public TaxStrategy{
public:
    virtual double Calculate(const Context& context){
        //***********
    }
};
//扩展
//*********************************
class FRTax : public TaxStrategy{
public:
	virtual double Calculate(const Context& context){
		//.........
	}
};
class SalesOrder{
private:
    TaxStrategy* strategy;
public:
    SalesOrder(StrategyFactory* strategyFactory){
        this->strategy = strategyFactory->NewStrategy();
    }
    ~SalesOrder(){
        delete this->strategy;
    }
    public double CalculateTax(){
        //...
        Context context();   
        double val = 
            strategy->Calculate(context); //多态调用
        //...
    } 
};

2)单一职责模式

在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任。

① Decorator 装饰模式
Demo
//业务操作
class Stream{
publicvirtual 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){
        //写内存流
    }  
};
//扩展操作
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){        
    }
    //...
};
void Process(){
    //运行时装配
    FileStream* s1=new FileStream();
    CryptoStream* s2=new CryptoStream(s1);
    BufferedStream* s3=new BufferedStream(s1);
    BufferedStream* s4=new BufferedStream(s2);
}
② Bridge 桥模式
Demo
class Messager{
protected:
     MessagerImp* messagerImp;//...
public:
    virtual void Login(string username, string password)=0;
    virtual void SendMessage(string message)=0;
    virtual void SendPicture(Image image)=0;   
    virtual ~Messager(){}
};

class MessagerImp{
public:
    virtual void PlaySound()=0;
    virtual void DrawShape()=0;
    virtual void WriteText()=0;
    virtual void Connect()=0;
    virtual MessagerImp(){}
};
//平台实现 n
class PCMessagerImp : public MessagerImp{
public:    
    virtual void PlaySound(){
        //**********
    }
    virtual void DrawShape(){
        //**********
    }
    virtual void WriteText(){
        //**********
    }
    virtual void Connect(){
        //**********
    }
};
class MobileMessagerImp : public MessagerImp{
public:
    virtual void PlaySound(){
        //==========
    }
    virtual void DrawShape(){
        //==========
    }
    virtual void WriteText(){
        //==========
    }
    virtual void Connect(){
        //==========
    }
};
//业务抽象 m
//类的数目:1+n+m
class MessagerLite :public Messager {   
public:  
    virtual void Login(string username, string password){       
        messagerImp->Connect();
        //........
    }
    virtual void SendMessage(string message){        
        messagerImp->WriteText();
        //........
    }
    virtual void SendPicture(Image image){   
        messagerImp->DrawShape();
        //........
    }
};
class MessagerPerfect  :public Messager {
public:   
    virtual void Login(string username, string password){        
        messagerImp->PlaySound();
        //********
        messagerImp->Connect();
        //........
    }
    virtual void SendMessage(string message){        
        messagerImp->PlaySound();
        //********
        messagerImp->WriteText();
        //........
    }
    virtual void SendPicture(Image image){        
        messagerImp->PlaySound();
        //********
        messagerImp->DrawShape();
        //........
    }
};

void Process(){
    //运行时装配
    MessagerImp* mImp=new PCMessagerImp();
    Messager *m =new Messager(mImp);
}

3)对象创建

① Factory Method 工程模式
DEMO
//工厂类
//抽象类
class ISplitter{
public:
    virtual void split()=0;
    virtual ~ISplitter(){}
};
//工厂基类
class SplitterFactory{
public:
    virtual ISplitter* CreateSplitter()=0;
    virtual ~SplitterFactory(){}
};

实现类

//具体类
class BinarySplitter : public ISplitter{    
};
class TxtSplitter: public ISplitter{   
};
class PictureSplitter: public ISplitter{  
};
class VideoSplitter: public ISplitter{   
};

//具体工厂
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();
    }
};
② Abstract Factory 抽象工厂模式
Demo
//数据库访问有关的基类
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()){
        }
    }
};
③ Prototype 原型模式
应用场景

创建的对象有一定的初始状态
深拷贝,确保一定的初始状态值不被改变。

DEMO
//抽象类
class ISplitter{
public:
    virtual void split()=0;
    virtual ISplitter* clone()=0; //通过克隆自己来创建对象  
    virtual ~ISplitter(){}
};
//具体类
class BinarySplitter : public ISplitter{
public:
    virtual ISplitter* clone(){
        return new BinarySplitter(*this);
    }
};
class TxtSplitter: public ISplitter{
public:
    virtual ISplitter* clone(){
        return new TxtSplitter(*this);
    }
};
class PictureSplitter: public ISplitter{
public:
    virtual ISplitter* clone(){
        return new PictureSplitter(*this);
    }
};
class VideoSplitter: public ISplitter{
public:
    virtual ISplitter* clone(){
        return new VideoSplitter(*this);
    }
};

class MainForm : public Form
{
    ISplitter*  prototype;//原型对象
public:   
    MainForm(ISplitter*  prototype){
        this->prototype=prototype;
    }    
	void Button1_Click(){
		ISplitter * splitter=
            prototype->clone(); //克隆原型  
        splitter->split();
	}
};
④ Builder 构建器
应用场景

某一对象的创建需要复杂的特定过程
以House对象的Builder为例

DEMO
class House{
    //....
};
class HouseBuilder {
public:
    House* GetResult(){
        return pHouse;
    }
    virtual ~HouseBuilder(){}
protected:
    House* pHouse;
	virtual void BuildPart1()=0;
    virtual void BuildPart2()=0;
    virtual void BuildPart3()=0;
    virtual void BuildPart4()=0;
    virtual void BuildPart5()=0;	
};
class StoneHouse: public House{    
};
class StoneHouseBuilder: public HouseBuilder{
protected:    
    virtual void BuildPart1(){
        //pHouse->Part1 = ...;
    }
    virtual void BuildPart2(){        
    }
    virtual void BuildPart3(){        
    }
    virtual void BuildPart4(){     
    }
    virtual void BuildPart5(){    
    }   
};
class HouseDirector{ 
public:
    HouseBuilder* pHouseBuilder;
    HouseDirector(HouseBuilder* pHouseBuilder){
        this->pHouseBuilder=pHouseBuilder;
    }
    House* Construct(){  
        pHouseBuilder->BuildPart1(); 
        for (int i = 0; i < 4; i++){
            pHouseBuilder->BuildPart2();
        } 
        bool flag=pHouseBuilder->BuildPart3(); 
        if(flag){
            pHouseBuilder->BuildPart4();
        }        
        pHouseBuilder->BuildPart5();       
        return pHouseBuilder->GetResult();
    }
};

4)对象性能

Singleton 单件模式
应用场景

避免对象过多实例化,从而影响性能或者对业务的需求造成严重的影响

DEMO
//单例模式模型
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;
}
Flyweight 享元模式
应用场景
DEMO
class Font {
private:
    //unique object key
    string key;
    //object state
    //....    
public:
    Font(const string& key){
        //...
    }
};
class FontFactory{
private:
    map<string,Font* > fontPool;    
public:
    Font* GetFont(const string& key){
        map<string,Font*>::iterator item=fontPool.find(key);      
        if(item!=footPool.end()){
            return fontPool[key];
        }
        else{
            Font* font = new Font(key);
            fontPool[key]= font;
            return font;
        }
    }    
    void clear(){
        //...
    }
};

5)接口隔离

Facade 门面模式
应用场景
DEMO
Proxy 代理模式
应用场景
DEMO
class ISubject{
public:
    virtual void process();
};
//Proxy的设计
class SubjectProxy: public ISubject{  
public:
    virtual void process(){
        //对RealSubject的一种间接访问
        //....
    }
};
class ClientApp{   
    ISubject* subject;    
public:   
    ClientApp(){
        subject=new SubjectProxy();
    }   
    void DoTask(){
        //...
        subject->process();       
        //....
    }
};
Adapter 适配器
应用场景
DEMO
//目标接口(新接口)
class ITarget{
public:
    virtual void process()=0;
};
//遗留接口(老接口)
class IAdaptee{
public:
    virtual void foo(int data)=0;
    virtual int bar()=0;
};
//遗留类型
class OldClass: public IAdaptee{
    //....
};
//对象适配器
class Adapter: public ITarget{ //继承
protected:
    IAdaptee* pAdaptee;//组合    
public:    
    Adapter(IAdaptee* pAdaptee){
        this->pAdaptee=pAdaptee;
    }    
    virtual void process(){
        int data=pAdaptee->bar();
        pAdaptee->foo(data);        
    }   
};
//类适配器
class Adapter: public ITarget,
               protected OldClass{ //多继承        
}
int main(){
    IAdaptee* pAdaptee=new OldClass();
    ITarget* pTarget=new Adapter(pAdaptee);
    pTarget->process(); 
}
Mediator 中介者
应用场景
DEMO

6)状态变化

State 状态模式
应用场景
DEMO
//原始代码模型
enum NetworkState
{
    Network_Open,
    Network_Close,
    Network_Connect,
};
class NetworkProcessor{   
    NetworkState state;
public:    
    void Operation1(){
        if (state == Network_Open){
            //**********
            state = Network_Close;
        }
        else if (state == Network_Close){
            //..........
            state = Network_Connect;
        }
        else if (state == Network_Connect){
            //$$$$$$$$$$
            state = Network_Open;
        }
    }
    public void Operation2(){
        if (state == Network_Open){          
            //**********
            state = Network_Connect;
        }
        else if (state == Network_Close){
            //.....
            state = Network_Open;
        }
        else if (state == Network_Connect){
            //$$$$$$$$$$
            state = Network_Close;
        }    
    }
    public void Operation3(){
    }
};

class NetworkState{
public:
    NetworkState* pNext;
    virtual void Operation1()=0;
    virtual void Operation2()=0;
    virtual void Operation3()=0;
    virtual ~NetworkState(){}
};
class OpenState :public NetworkState{    
    static NetworkState* m_instance;
public:
    static NetworkState* getInstance(){ // 单例模式,防止多次构建影响性能
        if (m_instance == nullptr) {
            m_instance = new OpenState();
        }
        return m_instance;
    }
    void Operation1(){        
        //**********
        pNext = CloseState::getInstance();
    }    
    void Operation2(){        
        //..........
        pNext = ConnectState::getInstance();
    }    
    void Operation3(){        
        //$$$$$$$$$$
        pNext = OpenState::getInstance();
    }        
};
class CloseState:public NetworkState{ }
//...
class NetworkProcessor{   
    NetworkState* pState;    
public:    
    NetworkProcessor(NetworkState* pState){       
        this->pState = pState;
    }    
    void Operation1(){
        //...
        pState->Operation1();
        pState = pState->pNext;
        //...
    }    
    void Operation2(){
        //...
        pState->Operation2();
        pState = pState->pNext;
        //...
    }    
    void Operation3(){
        //...
        pState->Operation3();
        pState = pState->pNext;
        //...
    }
};
Memento 备忘录
应用场景
DEMO
class Memento
{
    string state;
    //..
public:
    Memento(const string & s) : state(s) {}
    string getState() const { return state; }
    void setState(const string & s) { state = s; }
};
class Originator
{
    string state;
    //....
public:
    Originator() {}
    Memento createMomento() {
        Memento m(state);
        return m;
    }
    void setMomento(const Memento & m) {
        state = m.getState();
    }
};



int main()
{
    Originator orginator;
    
    //捕获对象状态,存储到备忘录
    Memento mem = orginator.createMomento();
    
    //... 改变orginator状态
    
    //从备忘录中恢复
    orginator.setMomento(memento);  
}

7)数据结构

Composite 组合模式
应用场景
DEMO
#include <iostream>
#include <list>
#include <string>
#include <algorithm>
using namespace std;
class Component
{
public:
    virtual void process() = 0;
    virtual ~Component(){}
};
//树节点
class Composite : public Component{    
    string name;
    list<Component*> elements;
public:
    Composite(const string & s) : name(s) {} 
    void add(Component* element) {
        elements.push_back(element);
    }
    void remove(Component* element){
        elements.remove(element);
    }   
    void process(){      
        //1. process current node     
        //2. process leaf nodes
        for (auto &e : elements)
            e->process(); //多态调用         
    }
};
//叶子节点
class Leaf : public Component{
    string name;
public:
    Leaf(string s) : name(s) {}      
    void process(){
        //process current node
    }
};
void Invoke(Component & c){
    //...
    c.process();
    //...
}
int main()
{
    Composite root("root");
    Composite treeNode1("treeNode1");
    Composite treeNode2("treeNode2");
    Composite treeNode3("treeNode3");
    Composite treeNode4("treeNode4");
    Leaf leat1("left1");
    Leaf leat2("left2");
    
    root.add(&treeNode1);
    treeNode1.add(&treeNode2);
    treeNode2.add(&leaf1);
    
    root.add(&treeNode3);
    treeNode3.add(&treeNode4);
    treeNode4.add(&leaf2);
    
    process(root);
    process(leaf2);
    process(treeNode3);
}
Iterator 迭代器模式
应用场景
DEMO
template<typename T>
class Iterator
{
public:
    virtual void first() = 0;
    virtual void next() = 0;
    virtual bool isDone() const = 0;
    virtual T& current() = 0;
};
template<typename T>
class MyCollection{  
public:
    Iterator<T> GetIterator(){
        //...
    }    
};
template<typename T>
class CollectionIterator : public Iterator<T>{
    MyCollection<T> mc;
public:   
    CollectionIterator(const MyCollection<T> & c): mc(c){ }    
    void first() override {        
    }
    void next() override {       
    }
    bool isDone() const override{        
    }
    T& current() override{        
    }
};

void MyAlgorithm()
{
    MyCollection<int> mc;    
    Iterator<int> iter= mc.GetIterator();   
    for (iter.first(); !iter.isDone(); iter.next()){
        cout << iter.current() << endl;
    }    
}
Chain of Resposibility 责任链模式
应用场景
DEMO
#include <iostream>
#include <string>
using namespace std;
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;
}

8)行为变化

Command 命令模式
应用场景
DEMO
#include <iostream>
#include <vector>
#include <string>
using namespace std;
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(receiver, "Arg ###");
    ConcreteCommand2 command2(receiver, "Arg $$$");    
    MacroCommand macro;
    macro.addCommand(&command1);
    macro.addCommand(&command2); 
    macro.execute();
}
Visitor 访问器
应用场景
DEMO
#include <iostream>
using namespace std;
class Visitor;
class Element
{
public:
    virtual void accept(Visitor& visitor) = 0; //第一次多态辨析
    virtual ~Element(){}
};
class ElementA : public Element
{
public:
    void accept(Visitor &visitor) override {
        visitor.visitElementA(*this);
    }
};
class ElementB : public Element
{
public:
    void accept(Visitor &visitor) override {
        visitor.visitElementB(*this); //第二次多态辨析
    }
};
class Visitor{
public:
    virtual void visitElementA(ElementA& element) = 0;
    virtual void visitElementB(ElementB& element) = 0;   
    virtual ~Visitor(){}
};
//==================================
//扩展1
class Visitor1 : public Visitor{
public:
    void visitElementA(ElementA& element) override{
        cout << "Visitor1 is processing ElementA" << endl;
    }        
    void visitElementB(ElementB& element) override{
        cout << "Visitor1 is processing ElementB" << endl;
    }
};     
//扩展2
class Visitor2 : public Visitor{
public:
    void visitElementA(ElementA& element) override {
        cout << "Visitor2 is processing ElementA" << endl;
    }   
    void visitElementB(ElementB& element) override {
        cout << "Visitor2 is processing ElementB" << endl;
    }
};     
int main()
{
    Visitor2 visitor;
    ElementB elementB;
    elementB.accept(visitor);// double dispatch
   
    ElementA elementA;
    elementA.accept(visitor);  
    return 0;
}

9)领域问题

Interpreter 解析器
应用场景
DEMO
#include <iostream>
#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;
    }    
    int interpreter(map<char, int> var) override {
        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){        
    }
    int interpreter(map<char, int> var) override {
        return left->interpreter(var) + right->interpreter(var);
    }    
};
//减法运算
class SubExpression : public SymbolExpression {   
public:
    SubExpression(Expression* left, Expression* right):
        SymbolExpression(left,right){        
    }
    int interpreter(map<char, int> var) override {
        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]));
        }
    }
    Expression* expression = expStack.top();
    return expression;
}
void release(Expression* expression){   
    //释放表达式树的节点内存...
}
int main(int argc, const char * argv[]) {
    string expStr = "a+b-c+d-e";
    map<char, int> var;
    var.insert(make_pair('a',5));
    var.insert(make_pair('b',2));
    var.insert(make_pair('c',1));
    var.insert(make_pair('d',6));
    var.insert(make_pair('e',10));
    Expression* expression= analyse(expStr); 
    int result=expression->interpreter(var);
    cout<<result<<endl;  
    release(expression); 
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值