四、设计模式 - 观察者模式(Observer Method)

1、动机

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

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

2、show me the code(注:伪码的形式)

假设我们现在有一个需求:把一个上G的资料分割成几个1百兆的文件,txtFilePath代表文件路径,txtFileNumber表示分割的个数

接下来我们想加一个进度条显示分割进展如何(假设ProgressBar是平台库支持的进度条显示类):

初学者可以使用上述方法解决问题,但是这种添加方式违背了依赖倒置原则,我们尝试加一个接口(观察者)用来看执行分割进度:

把实现细节放进DoProgress中:

上述我们就完成了对通知消息的解耦(IProgress接口就是观察者),看看我们这个条件的定义是“所有的观察者”,尝试添加多个观察者看看会怎么样:

添加多个观察者:

代码整理:

class MainForm
{
public:
	string path;
	int num;
	
public:
	MainForm(){//给路径path和分割数量num赋值等一些初始化操作}
	DoStep()
	{
		Notifier not;	//定义一个订阅对象
		FileSplitter splitter(path, num);
		splitter.addOberver(&not);	//添加观察者(订阅通知)
		splitter.split();//文件分割
		
		//...
		splitter.deleteObserver(&not);	//取消订阅
		splitter.GetPrgress();
	}	
};

class FileSplitter
{
public:
	string m_path;
	int m_size;
	vector<IOberver *> m_iOberver;//多个观察者
	
public:
	FileSplitter(string path,int num):m_path(path),m_size(num){}
	void split()
	{
		for(int i = 0; i < m_size; i++)
		{
			float value=(float)(i + 1) / (float)(m_size);
			update(value); //将进度传过来更新
		}
	}
	void addOberver(IOberver *ob)
	{
		m_iOberver->push_back(ob);
	}
	void deleteObserver(IOberver *ob)
	{
		m_iOberver->remove(ob);
	}
	void update(float value)
	{
		for(int num=0;num<m_iOberver.size();num++)
		{
			m_iOberver[num]->Update(value);//对每一个添加订阅的观察者的状态均更新
		}
	}
	void GetPrgress()
	{
		for(auto ii: m_iOberver)
		{
			cout << ii->GetState() << ", ";
		}
	}
};

class IOberver
{
public:
	virtual void Update(float value) = 0;
	virtual void GetState() = 0;
	virtual ~IOberver(){}
};

class Notifier: public IOberver
{
public:
	ProgressBar *m_progressBar;
public:
	void Update(float value)
	{
		m_progressBar->setValue(value);
	}
	void GetState()
	{
		m_progressBar->showBar();
	}
};

3、模式定义:

4、观察者模式结构

5、要点总结

     (1)使用面向对象的抽象,Observer使得我们可以独立的改变目标与观察者,从而是两者的依赖关系达到松耦合

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值