c++设计模式

37 篇文章 1 订阅

简介

image-20210929101632610

image-20210929102038290

image-20210929102202129

image-20210929102254456

以下面代码为例

一、分解

Shape.h

class Point{
public:
	int x;
	int y;
};

class Line{
public:
	Point start;
    Point end;

	Line(const Point& start, const Point& end){
        this->start = start;
        this->end = end;
    }

};

class Rect{
public:
	Point leftUp;
    int width;
	int height;

	Rect(const Point& leftUp, int width, int height){
        this->leftUp = leftUp;
        this->width = width;
		this->height = height;
    }

};

//增加
class Circle{
public:
    point center;//圆心
    int r;//半径
    
    Circle(const Point& c, int r){
		this->center = c;
		this->r = r;
		
	}
  

};
 


MainForm.cpp

//这里写的伪代码 继承的Form不管他
class MainForm : public Form {
private:
	Point p1;
	Point p2;

    //改变
	vector<Line> lineVector;
	vector<Rect> rectVector;
	//增加圆
	vector<Circle> circleVector;

public:
	MainForm(){
		//...
	}
protected:

	virtual void OnMouseDown(const MouseEventArgs& e);
	virtual void OnMouseUp(const MouseEventArgs& e);
	virtual void OnPaint(const PaintEventArgs& e);
};


void MainForm::OnMouseDown(const MouseEventArgs& e){
	p1.x = e.X;
	p1.y = e.Y;

	//...
	Form::OnMouseDown(e);
}

void MainForm::OnMouseUp(const MouseEventArgs& e){
	p2.x = e.X;
	p2.y = e.Y;

	if (rdoLine.Checked){
		Line line(p1, p2);
		lineVector.push_back(line);
	}
	else if (rdoRect.Checked){
		int width = abs(p2.x - p1.x);
		int height = abs(p2.y - p1.y);
		Rect rect(p1, width, height);
		rectVector.push_back(rect);
	}
	//增加
	else if (rdoCircle.Checked){
    	Point center=p1;
        int r=sqrt((p2.x-p1.x)*(p2.x-p1.x) + (p2.y-p1.y)*(p2.y-p1.y)); 
        Circle circle(center,r);
		circleVector.push_back(circle);
	}

	//...
	this->Refresh();

	Form::OnMouseUp(e);
}

void MainForm::OnPaint(const PaintEventArgs& e){

	//画线
	for (int i = 0; i < lineVector.size(); i++){
		e.Graphics.DrawLine(Pens.Red,
			lineVector[i].start.x, 
			lineVector[i].start.y,
			lineVector[i].end.x,
			lineVector[i].end.y);
	}

	//画矩阵
	for (int i = 0; i < rectVector.size(); i++){
		e.Graphics.DrawRectangle(Pens.Red,
			rectVector[i].leftUp,
			rectVector[i].width,
			rectVector[i].height);
	}

	//憎加
	//画圆
	for (int i = 0; i < circleVector.size(); i++){
		e.Graphics.DrawCircle(Pens.Red,
			circleVector[i].center,
                circleVector[i].r );
	}

	//...
	Form::OnPaint(e);
}


二、抽象

Shape.h

采用多态机制

class Shape{
public:
	virtual void Draw(const Graphics& g)=0;
	virtual ~Shape() { }
};


class Point{
public:
	int x;
	int y;
};

class Line: public Shape{
public:
	Point start;
	Point end;

	Line(const Point& start, const Point& end){
		this->start = start;
		this->end = end;
	}

	//实现自己的Draw,负责画自己
	virtual void Draw(const Graphics& g){
		g.DrawLine(Pens.Red, 
			start.x, start.y,end.x, end.y);
	}

};

class Rect: public Shape{
public:
	Point leftUp;
	int width;
	int height;

	Rect(const Point& leftUp, int width, int height){
		this->leftUp = leftUp;
		this->width = width;
		this->height = height;
	}

	//实现自己的Draw,负责画自己
	virtual void Draw(const Graphics& g){
		g.DrawRectangle(Pens.Red,
			leftUp,width,height);
	}

};

//增加圆的数据结构
class Circle : public Shape{
public:
    point center;//圆心
    int r;//半径
    
    Circle(const Point& c, int r){
		this->center = c;
		this->r = r;
		
	}
  
	//实现自己的Draw,负责画自己
	virtual void Draw(const Graphics& g){
		g.DrawCircle(Pens.Red,
			center,r);
	}

};


MainForm.cpp


class MainForm : public Form {
private:
	Point p1;
	Point p2;

	//针对所有形状 统一处理
	vector<Shape*> shapeVector;// shape*指针 是因为动态的机制

public:
	MainForm(){
		//...
	}
protected:

	virtual void OnMouseDown(const MouseEventArgs& e);
	virtual void OnMouseUp(const MouseEventArgs& e);
	virtual void OnPaint(const PaintEventArgs& e);
};


void MainForm::OnMouseDown(const MouseEventArgs& e){
	p1.x = e.X;
	p1.y = e.Y;

	//...
	Form::OnMouseDown(e);
}

void MainForm::OnMouseUp(const MouseEventArgs& e){
	p2.x = e.X;
	p2.y = e.Y;

	if (rdoLine.Checked){
		shapeVector.push_back(new Line(p1,p2));// new 一个堆指针
	}
	else if (rdoRect.Checked){
		int width = abs(p2.x - p1.x);
		int height = abs(p2.y - p1.y);
		shapeVector.push_back(new Rect(p1, width, height));
	}
	//增加
	else if (...){
		Point center=p1;
        int r=sqrt((p2.x-p1.x)*(p2.x-p1.x) + (p2.y-p1.y)*(p2.y-p1.y)); 
        Circle circle(center,r);
		shapeVector.push_back(circle);
	}

	//...
	this->Refresh();

	Form::OnMouseUp(e);
}

void MainForm::OnPaint(const PaintEventArgs& e){


	for (int i = 0; i < shapeVector.size(); i++){

		shapeVector[i]->Draw(e.Graphics); //多态调用,各负其责 是line就调用line的Draw  是Rect就调用Rect 的Draw
	}

	//...
	Form::OnPaint(e);
}


面向对象设计原则

image-20210929110509354

image-20210929110925832

image-20210929111353991

image-20210929111337613

这个其实就是扩展

image-20210929111433521

一个类不能乱指向

image-20210929111552066

子类继承父类,那肯定是有原因的

image-20210929111718153

不要把不必要的方法public出去,如果只是子类用就protected ,如果是本类用就private

image-20210929111850800

对象组合 比如就是 class a里面放一个 class b

继承 子类父类耦合度过高 就是 父类给子类暴露了太多东西

image-20210929112129828

封装变化点 一侧变化 一侧稳定

image-20210929112231008

image-20210929112311712

这里放的就是具体类型,违背面向对象原则

image-20210929112345448

image-20210929112358470

而这个则就是给了一个抽象接口,符合原则。

image-20210929112455843

image-20210929112534895

image-20210929112541595

其实软件的设计也是借鉴其他行业的原则!!!

image-20210929113116375

模板方法Template Method

image-20210930095041782

image-20210930095053276

image-20210930095103470

image-20210930095112821

image-20210930095120485

image-20210930095303479

image-20210930095420436

早绑定

这里的方法没有采用template_method

template_lib.cpp

//程序库开发人员
class Library{

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

    void Step3(){
		//...
    }

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

template_app.cpp

//应用程序开发人员
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();

}

image-20210930100450923

image-20210930100553826

一个晚的东西调用早的东西就是早绑定

晚绑定

采用 template method 的设计模式—前提是你要有稳定的骨架

程序主流程相对稳定

template_lib.cpp

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

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

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

        Step5();

    }
	virtual ~Library(){ }//基类的析构写成虚的  因为如果你 new一个子类出来 你要delete子类的话 如果基类的虚构没有写成虚的,可能子类不一定能调用到自己的析构

protected:
	
	void Step1() { //稳定
        //.....
    }
	void Step3() {//稳定
        //.....
    }
	void Step5() { //稳定
		//.....
	}
    //虚函数支持变化
	virtual bool Step2() = 0;//变化 
    virtual void Step4() =0; //变化
};

template_app.cpp

//应用程序开发人员
//继承库 来进行开发
class Application : public Library {
protected:
	virtual bool Step2(){
		//... 子类重写实现
    }

    virtual void Step4() {
		//... 子类重写实现
    }
};

int main()
	{
	//多态指针
	    Library* pLib=new Application();
	    lib->Run();//这里依然会根据流程来走

		delete pLib;//
	}
}

image-20210930100746466

image-20210930100757523

早的东西调用晚的东西就是晚绑定

image-20210930101046073

image-20210930101833536

红色的代表稳定

蓝色的代表不稳定

image-20210930101911329

策略模式

违背开闭原则

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){  //更改
			//...
		}

        //....
     }
    
};

这里要改动的东西多,同时if else 也消耗性能

符合开闭原则

策略模式


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); //多态调用 依赖于strategyFactory->NewStrategy()返回的是哪个子类对象
        //...
    }
    
};

image-20210930104008253

image-20210930104030608

image-20210930104159168

红色保持稳定,蓝色变化的部分

image-20210930104830324

观察者模式

image-20211005090859569

一、没有使用观察者模式

看代码

FileSplitter.cpp

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++){
			//...
			//分隔
			if (m_progressBar != nullptr)
			{
				float progressValue = m_fileNumber;
				progressValue = (i + 1) / progressValue;

				m_progressBar->setValue(progressValue);//更新进度条
			}
			
		}

	}
};

MainForm.cpp

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);

		splitter.split();

	}
};


二、使用了观察者设计模式

FileSplitter.cpp

class IProgress{
public:
	virtual void DoProgress(float value)=0;
	virtual ~IProgress(){}
};



class FileSplitter
{
	string m_filePath;
	int m_fileNumber;
	//ProgressBar* m_progressBar;// 通知控件 紧耦合
	List<IProgress*>  m_iprogressList; // 抽象通知机制,支持多个观察者(有了addIProgress和removeIProgress) 松耦合
	
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);//发送通知
		}

	}

	//加入IProgress
	void addIProgress(IProgress* iprogress){ 
		m_iprogressList.push_back(iprogress);
	}

	//删除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具体是什么类来选择
			itor++;
		}
	}
};

MainForm.cpp

//采用一对多的观察者模式  
//如果我们想用百分比的形式来做通知空间 我们可以再定义一个类 这个类来接受百分比的信息 然后在mainform类里面定义一个这个类的对象 然后add到m_iprogressList里面
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;
		CirclePercent cp;
		FileSplitter splitter(filePath, number);

		splitter.addIProgress(this); //订阅通知 
		splitter.addIProgress(&cn); //订阅通知
		splitter.addIProgress(&cp); //订阅通知
		splitter.split();

		splitter.removeIProgress(this);

	}

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

class ConsoleNotifier : public IProgress {
public:
	virtual void DoProgress(float value){
		cout << ".";
	}
};

//这边是自己加入的显示百分比 假如界面windows已经有一个圆盘形式百分比的组件了
class CirclePercent:public IProgress {
	CirclePanelPercent* circlePanelPercent;

public:
	virtual void DoProgress(float value) {
		circlePanelPercent->setvalue(value);
	}
};





image-20211005093413980

image-20211005093612821

红色的部分是稳定的部分,依赖的部分。 蓝色的是改变的部分

image-20211005093909661

装饰模式

image-20211005100131413

image-20211005100116846

image-20211005100446792

image-20211005102228996

对于扩展操作来说 既可以加密 也可以缓冲 加入有m个扩展操作 那么总共组合就是 (m+m-1+ ….+1)/2 m>2 ,n代表文件流种类。

decorator1.cpp

//业务操作
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){
        //写内存流
    }
    
};

//扩展操作
class CryptoFileStream :public FileStream{
public:
    virtual char Read(int number){
       
        //额外的加密操作...
        FileStream::Read(number);//读文件流
        
    }
    virtual void Seek(int position){
        //额外的加密操作...
        FileStream::Seek(position);//定位文件流
        //额外的加密操作...
    }
    virtual void Write(byte data){
        //额外的加密操作...
        FileStream::Write(data);//写文件流
        //额外的加密操作...
    }
};

class CryptoNetworkStream : :public NetworkStream{
public:
    virtual char Read(int number){
        
        //额外的加密操作... 这里重复了代码
        NetworkStream::Read(number);//读网络流
    }
    virtual void Seek(int position){
        //额外的加密操作... 这里重复了代码
        NetworkStream::Seek(position);//定位网络流
        //额外的加密操作...
    }
    virtual void Write(byte data){
        //额外的加密操作... 这里重复了代码
        NetworkStream::Write(data);//写网络流
        //额外的加密操作...
    }
};

class CryptoMemoryStream : public MemoryStream{
public:
    virtual char Read(int number){
        
        //额外的加密操作... 这里重复了代码
        MemoryStream::Read(number);//读内存流
    }
    virtual void Seek(int position){
        //额外的加密操作... 这里重复了代码
        MemoryStream::Seek(position);//定位内存流
        //额外的加密操作...
    }
    virtual void Write(byte data){
        //额外的加密操作... 这里重复了代码
        MemoryStream::Write(data);//写内存流
        //额外的加密操作...
    }
};

class BufferedFileStream : public FileStream{
    //...
};

class BufferedNetworkStream : public NetworkStream{
    //...
};

class BufferedMemoryStream : public MemoryStream{
    //...
}




class CryptoBufferedFileStream :public FileStream{
public:
    virtual char Read(int number){
        
        //额外的加密操作...
        //额外的缓冲操作...
        FileStream::Read(number);//读文件流
    }
    virtual void Seek(int position){
        //额外的加密操作...
        //额外的缓冲操作...
        FileStream::Seek(position);//定位文件流
        //额外的加密操作...
        //额外的缓冲操作...
    }
    virtual void Write(byte data){
        //额外的加密操作...
        //额外的缓冲操作...
        FileStream::Write(data);//写文件流
        //额外的加密操作...
        //额外的缓冲操作...
    }
};



void Process(){

        //编译时装配
    CryptoFileStream *fs1 = new CryptoFileStream();

    BufferedFileStream *fs2 = new BufferedFileStream();

    CryptoBufferedFileStream *fs3 =new CryptoBufferedFileStream();

}

可以看到上面有很多冗余的代码

decorator2.cpp

利用多态消除冗余(组合的方式)

//业务操作
//利用多态消除冗余
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){
        //写内存流
    }
    
};

//扩展操作 就是各种类型文件的读取 定位都在这里面操作
class CryptoStream: public Stream {//这里继承stream是为了完善接口的规范
    
    Stream* stream;//...

public:
    CryptoStream(Stream* stm):stream(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 Stream{
    
    Stream* stream;//...
    
public:
    BufferedStream(Stream* stm):stream(stm){
        
    }
    //...
};





void Process(){

    //运行时装配
    FileStream* s1=new FileStream();
    CryptoStream* s2=new CryptoStream(s1);
    
    BufferedStream* s3=new BufferedStream(s1);//对文件流的缓存
    
    BufferedStream* s4=new BufferedStream(s2);//对文件流的加密和缓存
    
    

}

decorator3.cpp

进一步完善

//业务操作
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){
        //写内存流
    }
    
};

//扩展操作

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);
    
    

}

image-20211005102253916

image-20211005102355802

主体和扩展应该分开

image-20211005102636622

image-20211005102715926红色代表稳定的部分,蓝色代表变化的部分

image-20211005102940559

桥模式

image-20211006093236260

image-20211006093243637

bridge1.cpp

继承太多了,导致类数目太多,代码冗余

class Messager{
public:
    virtual void Login(string username, string password)=0;
    virtual void SendMessage(string message)=0;
    virtual void SendPicture(Image image)=0;

    virtual void PlaySound()=0;
    virtual void DrawShape()=0;
    virtual void WriteText()=0;
    virtual void Connect()=0;
    
    virtual ~Messager(){}
};


//平台实现 n

class PCMessagerBase : public Messager{
public:
    
    virtual void PlaySound(){
        //**********
    }
    virtual void DrawShape(){
        //**********
    }
    virtual void WriteText(){
        //**********
    }
    virtual void Connect(){
        //**********
    }
};

class MobileMessagerBase : public Messager{
public:
    
    virtual void PlaySound(){
        //==========
    }
    virtual void DrawShape(){
        //==========
    }
    virtual void WriteText(){
        //==========
    }
    virtual void Connect(){
        //==========
    }
};



//业务抽象 m
//类的数目:1+n+m*n


class PCMessagerLite : public PCMessagerBase {
public:
    
    virtual void Login(string username, string password){
        
        PCMessagerBase::Connect();
        //........
    }
    virtual void SendMessage(string message){
        
        PCMessagerBase::WriteText();
        //........
    }
    virtual void SendPicture(Image image){
        
        PCMessagerBase::DrawShape();
        //........
    }
};



class PCMessagerPerfect : public PCMessagerBase {
public:
    
    virtual void Login(string username, string password){
        
        PCMessagerBase::PlaySound();
        //********
        PCMessagerBase::Connect();
        //........
    }
    virtual void SendMessage(string message){
        
        PCMessagerBase::PlaySound();
        //********
        PCMessagerBase::WriteText();
        //........
    }
    virtual void SendPicture(Image image){
        
        PCMessagerBase::PlaySound();
        //********
        PCMessagerBase::DrawShape();
        //........
    }
};


class MobileMessagerLite : public MobileMessagerBase {
public:
    
    virtual void Login(string username, string password){
        
        MobileMessagerBase::Connect();
        //........
    }
    virtual void SendMessage(string message){
        
        MobileMessagerBase::WriteText();
        //........
    }
    virtual void SendPicture(Image image){
        
        MobileMessagerBase::DrawShape();
        //........
    }
};


class MobileMessagerPerfect : public MobileMessagerBase {
public:
    
    virtual void Login(string username, string password){
        
        MobileMessagerBase::PlaySound();
        //********
        MobileMessagerBase::Connect();
        //........
    }
    virtual void SendMessage(string message){
        
        MobileMessagerBase::PlaySound();
        //********
        MobileMessagerBase::WriteText();
        //........
    }
    virtual void SendPicture(Image image){
        
        MobileMessagerBase::PlaySound();
        //********
        MobileMessagerBase::DrawShape();
        //........
    }
};


void Process(){
        //编译时装配
        Messager *m =
            new MobileMessagerPerfect();
}



bridge2.cpp

将平台与业务分离,采用组合的方法,减少类的数目,减少代码的冗余

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*n


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(){
        //运行时装配
        //编译的时候类ide数目1+n+m
        //运行时实现的功能数目和之前没有使用桥模式一样
        //比如想要对pc平台操作
            MessagerImp* imp = new PCMessagerImp();
            Messager *m= new Messager(imp);//调用构造 说明m这个类里面的messagerImp指针指向PCMessagerImp子类 
                                            //因此下面的MessagerLite和MessagerPerfect调用的都是PC平台下的方法
            m->Login();
            m->SendMessage();
            m->SendPicture();
}



image-20211006094403801

image-20211006094705463

红色稳定,蓝色不稳定.

image-20211006094611645

工厂方法模式

没有使用工厂设计模式

MainForm.cpp

class MainForm : public Form
{
	TextBox* txtFilePath;
	TextBox* txtFileNumber;
	ProgressBar* progressBar;

public:
	void Button1_Click(){


        
		ISplitter * splitter=
            new BinarySplitter();//依赖具体类
        
        splitter->split();

	}
};

FileSplitter.cpp

class ISplitter{
public:
    virtual void split()=0;
    virtual ~ISplitter(){}
};

class BinarySplitter : public ISplitter{
    
};

class TxtSplitter: public ISplitter{
    
};

class PictureSplitter: public ISplitter{
    
};

class VideoSplitter: public ISplitter{
    
};


我们如何让才能让mainform不依赖具体类那呢?采用工厂设计模式

使用工厂设计模式

MainForm.cpp

class MainForm : public Form
{
    SplitterFactory*  factory;//工厂

public:
    
    MainForm(SplitterFactory*  factory){//创建什么类型的工厂在这里面执行 
        this->factory=factory;
    }
    
	void Button1_Click(){

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

	}
};

//怎么使用呢
int main()
{
    SplitterFactory* f = new BinarySplitterFactory();//以这个为例子
    MainForm *m=new MainForm(f) ;
    m->Button1_Click();

    return 0;
}




ISplitterFactory.cpp


//抽象类
class ISplitter{
public:
    virtual void split()=0;
    virtual ~ISplitter(){}
};


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




FileSplitter.cpp



//具体类
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();
    }
};


image-20211006102203491

image-20211006102329732

image-20211006102345658

image-20211006102320723

红色稳定,蓝色不稳定,mainform继承红色。

目的就是把红色和蓝色分离

image-20211006102509272

抽象工厂

image-20211007100650458

image-20211007100918369

下面三段代码都是关于不同数据库访问的代码

EmployeeDAO1.cpp


class EmployeeDAO{
//对数据库的访问 这个类不能访问不同类型的数据库    
public:
    vector<EmployeeDO> GetEmployees(){
        SqlConnection* connection =
            new SqlConnection();
        connection->ConnectionString = "...";

        SqlCommand* command =
            new SqlCommand();
        command->CommandText="...";
        command->SetConnection(connection);

        SqlDataReader* reader = command->ExecuteReader();
        while (reader->Read()){

        }

    }
};

EmployeeDAO2.cpp

采用工厂模式


//数据库访问有关的基类
class IDBConnection{
    
};
class IDBConnectionFactory{
public:
    virtual IDBConnection* CreateDBConnection()=0;
};

//数据库访问有关的基类
class IDBCommand{
    
};
class IDBCommandFactory{
public:
    virtual IDBCommand* CreateDBCommand()=0;
};

//数据库访问有关的基类
class IDataReader{
    
};
class IDataReaderFactory{
public:
    virtual IDataReader* CreateDataReader()=0;
};

//支持SQL Server
class SqlConnection: public IDBConnection{
    
};
class SqlConnectionFactory:public IDBConnectionFactory{
    
};

class SqlCommand: public IDBCommand{
    
};
class SqlCommandFactory:public IDBCommandFactory{
    
};

class SqlDataReader: public IDataReader{
    
};
class SqlDataReaderFactory:public IDataReaderFactory{
    
};

//支持Oracle
class OracleConnection: public OracleConnection{
    
};
class OracleConnectionFactory:public OracleConnectionFactory{
    
};
class OracleCommand: public IDBCommand{
    
};
class OracleCommandFactory:public OracleCommandFactory{
    
};
class OracleDataReader: public IDataReader{
    
};
class OracleDataReaderFactory:public OracleDataReaderFactory{
    
};

class EmployeeDAO
{
    IDBConnectionFactory* dbConnectionFactory;
    IDBCommandFactory* dbCommandFactory;
    IDataReaderFactory* dataReaderFactory;
    public:
    vector<EmployeeDO> GetEmployees()
    {
        IDBConnection* connection=dbConnectionFactory->CreateDBConnection();//dbConnectionFactory在构造函数里赋值
        connection->ConnectionString("...");

        IDBCommand* command =
            dbCommandFactory->CreateDBCommand();
        command->CommandText("...");
        command->SetConnection(connection); //关联性
        IDBDataReader* reader = command->ExecuteReader(); //关联性
        while (reader->Read()){

        }
        
    }
}

从上面的代码可以看出这里的工厂模式针对每种不同的数据库,都弄了一个工厂

EmployeeDAO3.cpp

可以看到上面代码同种类型的数据库的连接 命令读取都是相关联的,那么我们就把 IDBConnection IDBCommand IDataReader的创建放在一个类里面


//数据库访问有关的基类
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 OracleDBFactory:public IDBFactory{
public:
    virtual IDBConnection* CreateDBConnection()=0;
    virtual IDBCommand* CreateDBCommand()=0;
    virtual IDataReader* CreateDataReader()=0;
 
};

class EmployeeDAO{
    IDBFactory* dbFactory;
    
public:
    vector<EmployeeDO> GetEmployees(){
        IDBConnection* connection =
            dbFactory->CreateDBConnection();//dbFactory在构造函数里面赋值
        connection->ConnectionString("...");

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

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

        }

    }
};

可以看出抽象模式和工厂模式很类似,工厂模式就有点像是特殊的抽象模式。

image-20211007102113334

image-20211007102253229

红色的代表稳定,绿色和蓝色代表变化

AbstractFactory相当于是IDBFactory

AbstractProductA相当于是IDBConnection

AbstractProductB相当于是IDBCommand

image-20211007102457687

原型模式Prototype

image-20211007104819956

image-20211007104757919

client.cpp

class MainForm : public Form
{
    ISplitter*  prototype;//原型对象

public:
    
    MainForm(ISplitter*  prototype){
        this->prototype=prototype;
    }
    
	void Button1_Click(){

		ISplitter * splitter=
            prototype->clone(); //克隆原型
        
        splitter->split();
        
        

	}
};

Prototype.cpp

//抽象类
class ISplitter
{
    public:
    virtual void split()=0;
    virtual ISplitter* clone()=0; //通过克隆自己来创建对象
    
    virtual ~ISplitter(){}
}
    

ConcretePrototype.cpp

//具体类
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);//深拷贝构造自己 实现克隆自己
    }
};

可以和工厂模式那一章节做对比,如果说实现的类里面有些中间状态很复杂,你又想保留,建议用原型模式 ,也就是拷贝。

image-20211007105540830

image-20211007105654800

红色是稳定部分 抽象类 ISplitter

蓝色是变化部分,也就是具体类 BinarySplitter TxtSplitter等

image-20211007110001971

构建器

image-20211008095448590

image-20211008095441320

//builder模式其实就是把几个负责的分成好几个类
/**
* 比如我们把House 和 HouseBuilder分离开来,并且真正的构建再单独写一个类HouseDirector 
* 让HouseDirector里面有HouseBuilder指针,这样可以调用到构建房子需要用到的函数,同时对于不同类型的房子构建类来继承 HouseBuilder(重载构建房子的子函数)  , 不同类型的房子类继承House
* 最后HouseDirector应该有一个函数可以返回返回House指针,用户就可以得到构建后房子的类了。
*/

class House{
    //....
};

class HouseBuilder {
public:
    House* GetResult(){//获得house指针

        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 = ...;//这里面用到house里面的东西
    }
    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();
    }
};

image-20211008100954176

红色的代表稳定,蓝色的代表变化

这里面就是指

HouseBuilder HouseDirector稳定

StoneHouseBuilder等具体的子类是变化的

image-20211008095429692

image-20211008100317930

单件模式

image-20211008101346490

image-20211008101627403



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;//保证唯一

}






//线程安全版本,但锁的代价过高---因为对于都是读操作的线程是浪费的。
//就是只有35行执行结束了,才会释放锁,其他线程才能到32行 这时候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();//默认的顺序:先分配内存 再调用构造器,再把地址赋值给m_instance  
                                        //reorder之后顺序有可能为:先分配内存 ,把地址赋值给m_instance,再调用构造器  这样就导致读存在问题 因为只是分配了原生的内存,没有执行构造器
        }
    }
    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);//tmp这个指针乐意屏蔽编译器的reorder
    std::atomic_thread_fence(std::memory_order_acquire);//内存fence (内存的屏障 内存reorder的保护)
    //下面的tmp就不会被reorder了
    if (tmp == nullptr) {
        std::lock_guard<std::mutex> lock(m_mutex);//上锁
        tmp = m_instance.load(std::memory_order_relaxed);//1内存
        if (tmp == nullptr) {//
            tmp = new Singleton;//2 构造 不会被reorder一定是先执行它 再执行构造器,再把值返回
            std::atomic_thread_fence(std::memory_order_release);//释放内存fence
            m_instance.store(tmp, std::memory_order_relaxed);//3返回到m_instance
        }
    }
    return tmp;
}


image-20211008101636419

image-20211008104455533

image-20211008104436891

享元模式

image-20211009094915487

image-20211009095009865


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(){
        //...
    }

};

image-20211009095949006

image-20211009094955625

image-20211009095631933

门面模式

image-20211009100259963

image-20211009100506349

image-20211009101029296

image-20211009101118131

image-20211009101223565

以数据库为例

红色的部分 是稳定的,比如返回数据库对象啊什么的

蓝色部分改变的,比如数据表结构,数据连接方式

image-20211009101615012

代理模式

image-20211010095737128

image-20211010094753604

client.cpp

没有使用代理模式

class ISubject{
public:
    virtual void process();
};


class RealSubject: public ISubject{
public:
    virtual void process(){
        //....
    }
};

class ClientApp{
    
    ISubject* subject;
    
public:
    
    ClientApp(){
        subject=new RealSubject();
    }
    
    void DoTask(){
        //...
        subject->process();
        
        //....
    }
};

proxy.cpp

使用了代理模式

class ISubject{
public:
    virtual void process();
};


//Proxy的设计
class SubjectProxy: public ISubject{
    
    
public:
    virtual void process(){
        //对RealSubject的一种间接访问  就是这里和上面的client.cpp有区别 这里面实际上会比上面的复杂很多 ,用SubjectProxy类进行隔离。
        //....
    }
};

class ClientApp{
    
    ISubject* subject;
    
public:
    
    ClientApp(){
        subject=new SubjectProxy();
    }
    
    void DoTask(){
        //...
        subject->process();
        
        //....
    }
};

image-20211010094810110

image-20211010094930262

image-20211010095749521

适配器

image-20211010100214229

image-20211010100233613

老的东西放在新的里面使用

image-20211010100257546

//目标接口(新接口)
class ITarget{
public:
    virtual void process()=0;
};

//遗留接口(老接口)
class IAdaptee{
public:
    virtual void foo(int data)=0;
    virtual int bar()=0;
};

//遗留类型
class OldClass: public IAdaptee{
    //.... 重写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{ //多继承  // protected 和private继承可以叫做实现继承 就是我没有继承你的接口,但是我用你的实现
               
               
}


int main(){
    IAdaptee* pAdaptee=new OldClass();//旧类对象
    
    
    ITarget* pTarget=new Adapter(pAdaptee);//旧类对象塞进adpater里面产生新类对象
    pTarget->process();
    
    
}

//这些也是用到了adapter
class stack{
    deqeue container;
    
};

class queue{
    deqeue container;
    
};


image-20211010100345700

image-20211010100456157

image-20211010101640017

中介者模式

image-20211010101748905

image-20211010102357150

image-20211010102709442

image-20211010102908617

image-20211010103102082

image-20211010103639506

状态模式

image-20211011100404809

image-20211011101808378

没有使用状态模式

cenum 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(){

    }
};



上面的代码采用了很多if else

使用状态模式

class NetworkState{

public:
    NetworkState* pNext;//指向状态改变后的状态
    virtual void Operation1()=0;
    virtual void Operation2()=0;
    virtual void Operation3()=0;

    virtual ~NetworkState(){}
};

//我们把各个不同state的operation都分别在不同的state类里面实现 这样程序的框架更加明显 也更方便后期代码的添加和修改

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{
    
    static NetworkState* m_instance;
public:
    static NetworkState* getInstance(){
        if (m_instance == nullptr) {
            m_instance = new CloseState();
        }
        return m_instance;
    }

    void Operation1(){
        
        //**********
        pNext = ConnectState::getInstance();
    }
    
    void Operation2(){
        
        //..........
         pNext = OpenState::getInstance();
    }
    
    void Operation3(){
        
        //$$$$$$$$$$
        
    }
};


//
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;
        //...
    }
    
    
    
};

image-20211011101816011

image-20211011101428026

红色的是稳定的

蓝色的是变化的

image-20211011101835037

备忘录Memento

image-20211011103214512

image-20211011103228490


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(mem);

   
    
}

image-20211011103249332

image-20211011104159333

image-20211011104335952

组合模式

image-20211011105143403

image-20211011105224458

#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; //这里list里面有可能是 Composite 也有可能是 Leaf
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);
  
}

image-20211011105241198

image-20211011110911509

迭代器

image-20211011111154252

image-20211011111226214

现在在c++里面来看 这个模式已经是落伍了 因为它是基于虚函数面向对象的迭代器 相比于stl 泛型编程基于模板的多态迭代器 效率要低。

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;
    }
    
}


image-20211011111250170

image-20211011112438893

image-20211011112424097

职责链

image-20211011112618588

image-20211011112911033

#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;//多态指针指向自身 形成链表  这样j
    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;
}

image-20211011113759249

image-20211011113901978

image-20211011114053137
void next() override {

}
bool isDone() const override{
    
}
T& current() override{
    
}

};

void MyAlgorithm()
{
MyCollection mc;

Iterator<int> iter= mc.GetIterator();

for (iter.first(); !iter.isDone(); iter.next()){//虚函数是运行时多态 效率低于编译时多态(编译时已经把工作做了 就不需要运行的时候再计算函数地址了)
    cout << iter.current() << endl;
}

}




[外链图片转存中...(img-fyKsXrfx-1633924054004)]

[外链图片转存中...(img-CEbxcAeZ-1633924054004)]

[外链图片转存中...(img-z2eQhKpq-1633924054004)]

# 职责链

[外链图片转存中...(img-MLPjq5ZX-1633924054005)]

[外链图片转存中...(img-CC0IPwVj-1633924054005)]

~~~c++
#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;//多态指针指向自身 形成链表  这样j
    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;
}

[外链图片转存中…(img-mifDppys-1633924054005)]

[外链图片转存中…(img-0p6AM0Rn-1633924054006)]

[外链图片转存中…(img-Ax0WbJZd-1633924054006)]

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值