C++设计模式--1.组件协作

内容总结自李建忠老师C++设计模式

1.分类

1.组件协作
  • Template Method
  • Strategy
  • Observer/Event
2.单一职责
  • Decorator
  • Bridge
3.对象创建
  • Factory Method
  • Abstract Factory
  • Prototype
  • Builder
4.对象性能
  • Singleton
  • Flyweight
5.接口隔离
  • Facade
  • Proxy
  • Mediator
  • Adapter
6.状态变化
  • Memento
  • State
7.数据结构
  • Composite
  • Iterator
  • Chain of Resposibility
8.行为变化
  • Command
  • Visitor

在这里插入图片描述

2.重构关键技法

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

3.组件协作

现代软件专业分工之后的第一个结果就是 “框架和应用程序的划分”,"组件协作"模式通过晚期绑定,来实现框架和应用程序之间的松耦合,是二者之间协作时常用的模式

1.Template Method

在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现。
如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求?

在这里插入图片描述

//面向结构

//程序库
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();
	}
}

在这里插入图片描述

//面象对象

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

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2. Strategy 策略模式

在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂,而且有时候支持不使用的算法也是一个性能负担。

如何在运行时根据需要透明的更改对象的算法?将算法与对象本身解耦,从而避免上述问题?

在这里插入图片描述

//strategy

//old
enum TaxBase{
	CN_Tax,
	US_Tax,
	DE_Tax,
	FR_Tax     //变化
}


class SalesOrder{
	TaxBase tax;
public:
	double CalculateTax(){
		if(tax == CN_Tax){

		}else if(tax == US_Tax){

		}else if(tax == DE_Tax){

		}else if(tax == FR_Tax){   //变化

		}

	}
}


//Strategy

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 SalesOrder{
private:
	TaxStrategy* strategy;     //指针,基类抽象,不能用TaxStrategy strategy;对象,没有多态性

public:
	SalesOrder(StrategyFactory* strategyFactory){
		this->strategy=strategyFactory->NewStrategy();
	}
    ~SalesOrder(){
		delete this->strategy;
	}

public double CalculateTax(){
		Context context();
		double val=strategy->Calculate(context);   //多态调用
	}

}

在这里插入图片描述
在这里插入图片描述

3. Observer 观察者模式

在软件构建过程中,我们需要为某些对象建立一种"通知依赖关系"----一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,将使软件不能很好的抵御变化。

使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。

在这里插入图片描述

//observe

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


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(){
		//...
		for(int i=0; i< m_fileNumber; i++){
			if(m_progressBar!=nullptr){
				m_progressBar->setValue((i+1)/m_fileNumber);  //更新
			}
			
		}
	}
}


//--------------

//observe

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

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






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;  //抽象通知机制,支持多个观察者

public:
	FileSplitter(const string& filePath, int fileNumber):m_filePath(filePath),m_fileNumber(fileNumber){

	}


	void split(){
		//...
		for(int i=0; i< m_fileNumber; i++){
			if(m_progressBar!=nullptr){
				float progressValue = m_fileNumber;
				progressValue = (i + 1) / progressValue;
				onProgress(progressValue);  //更新
			}
			
		}
	}

	void addIProgress(IProgress* iprogress){
		m_iprogressList.add(iproress);
	}
	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++;
		}
}

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值