设计模式学习记录2-组件协作模式

Template Method

1.结构化软件设计流程

在这里插入图片描述

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

2.面向对象软件设计流程

在这里插入图片描述

库代码

// 程序库开发人员
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() { ... } // 稳定
	vitural bool Step2() { ... }  = 0 // 子类重写实现
	vitural void Step4() { ... }  = 0 // 子类重写实现

应用代码

// 应用程序开发人员
class Application : public Library
{
protected:
	vitural bool Step2() { ... } // 子类重写实现
	vitural void Step4() { ... } // 子类重写实现
}

main函数

int main()
{
	Library* plib = new Application ();
	plib->run();
	delete plib;
}

3.模式定义

定义一个操作中的算法骨架(稳定),而将一些步骤延迟(变化)到子类种。template method使得子类可以不改变(复用)一个算法的结构即可以重定义(override重写)该算法的某些特定步骤。

4.结构

在这里插入图片描述

5.要点总结

在这里插入图片描述

策略模式

1.动机

在这里插入图片描述

2.策略1

可能会在以后增加其他国家的税额计算需要增加枚举类型, 违反开放封闭原则,违背了复用性,尽可能用扩展的方式解决问题

// 不同国家税额计算
enum TaxBase{
	CN_Tax;
	US_Tax;
	DE_Tax;
	// 增加
}
class SalesOrder{
private:
	TaxBase tax;
public:
	// ...
	if(tax == CN_Tax){
		//CN...
	}else if(tax == US_Tax){
		//US...
	}else if(tax == US_Tax){
		//DE...
	} // 增加 else if(...)
	
	//...
}

3.策略2

遵循了开放封闭原则

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->NewStragety(); // 工厂模式
	}
	~SalesOrder() {
		delete this->strategy;
	}

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

};

4.模式定义

在这里插入图片描述

5.结构

在这里插入图片描述

6.总结

在这里插入图片描述

观察者模式

1.动机

在这里插入图片描述

代码1

紧耦合,违法依赖倒置原则:高层模块(稳定)不应该依赖于低层模块(变化),二者都应该依赖于抽象(稳定)


class FileSplitter1 {
private:
	string my_filePath;
	int m_fileNumber;

	// 增加文件进度条
	// 功能: 通知控件
	ProgressBar* m_progressBar; // 具体的通知控件
public:
	FileSplitter1(const string& filePath, int fileNumber, ProgressBar* progressBar):
		my_filePath(filePath),m_fileNumber(fileNumber), m_progressBar(progressBar){}
	void split() {
		// 1.读取大文件
		// 2. 分批次向小文件中写入
		for (int i = 0; i < m_fileNumber; i++) {
			if (m_progressBar != nullptr) {
				m_progressBar->set_value((i + 1) / m_fileNumber);
			}
		}

	}
};

class MainForm : public Form {
private:
	TextBox* txtFilePath;
	TextBox* txtFIleNumber;
	ProgressBar* m_progressBar;
public:
	void Button1_Click() {
		string filePath = txtFilePath->getPath();
		int number = atoi(txtFIleNumber->getText().c_str());

		FileSplitter1 splitter(filePath, number, m_progressBar);

		splitter.split();
	}
};

代码2

松耦合,符合依赖倒置原则

class FileSplitter2 {
private:
	string my_filePath;
	int m_fileNumber;

	// 增加文件进度条
	// 功能: 通知控件
	IProgress* m_iprogress; // 抽象的通知机制
	// List<IProgress*> m_iProgressVector; // 抽象通知机制,支持多个观察值
public:
	FileSplitter2(const string& filePath, int fileNumber, IProgress* iprogress) :
		my_filePath(filePath), m_fileNumber(fileNumber), m_iprogress(iprogress) {}
	// void add_IProgress(IProgress* iprogress)
	// void remove_IProgress(IProgress* iprogress)
	void split() {
		// 1.读取大文件
		// 2. 分批次向小文件中写入
		for (int i = 0; i < m_fileNumber; i++) {
			if (m_iprogress != nullptr) {
				float progressValue = m_fileNumber;
				progressValue = (i + 1) / progressValue;
				m_iprogress->set_value(progressValue);
			}
		}

	}
};


class MainForm : public Form, public IProgress{
private:
	TextBox* txtFilePath;
	TextBox* txtFIleNumber;
	ProgressBar* progressBar;
public:
	void Button1_Click() {
		string filePath = txtFilePath->getPath();
		int number = atoi(txtFIleNumber->getText().c_str());

		FileSplitter2 splitter(filePath, number, this);

		splitter.split();
	}
	virtual void DoProgress(float value) {
		progressBar->set_value(value);
	}
};


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

结构

在这里插入图片描述

要点总结

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值