B站设计模式第3章——Observer / Event

本文详细解读了Observer模式在FileSplitter类中的应用,展示了如何通过观察者模式实现在文件分割过程中,当文件进度改变时自动通知多个观察者,如进度条和控制台。通过对比不同实现方式,突出了模式的松耦合特性。
摘要由CSDN通过智能技术生成

Observer 定义

 对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新

 Observer 要点总结

(1) 使用面向对象的抽象,Observer模式使得我们 可以独立地改变目标与观察者 ,从而使二者之间的依赖关系达致 松耦合

(2) 目标发送通知时, 无需指定观察者 ,通知(可以携带通知信息作 为参数)会自动传播。

(3) 观察者自己决定是否需要订阅通知,目标对象对此一无所知。

(4) Observer模式是基于事件的UI框架中非常常用的设计模式,也是 MVC模式的重要组成部分。

FileSplitter1.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++){
			//...
			float progressValue = m_fileNumber;
			progressValue = (i + 1) / progressValue;
			m_progressBar->setValue(progressValue);
		}
	}
};

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


FileSplitter2.cpp

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

MainForm2.cpp

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值