设计模式(四)——组件协作模式-Observer

对象模式所属类别简介-组件协作模式

组件模式通过晚绑定来实现松耦合(virtual)
组件协作模式包含以下三种:
TemplateMethod
Observer(event)
strategy

当前模式简介Observer(event)

需求

写一个文件分割器,把一个大文件分割成五个小文件,并且显示进度。

设计一

#include "stdafx.h"
#include <iostream>
using namespace std;
class ProgressBar  //进度
{
public:
	ProgressBar(){ m_progress = 0; }
	int m_progress;
	void SetProgress(int i) { this->m_progress = i;}
	int GetProgress() { 
		std::cout << "MainForm进度=" << this->m_progress << std::endl; return this->m_progress; };
};

class CFileSplitter //分割
{
public:
	CFileSplitter(ProgressBar* progressBar){ this->m_progressBar = progressBar; }
	ProgressBar* m_progressBar;
	void SplitFile(string vName)
	{ 
		std::cout << __FUNCTION__ << std::endl;
		std::cout << "hello" << std::endl;
		for (int i = 0; i < 5; i++)
		{
			m_progressBar->SetProgress(i);
			m_progressBar->GetProgress();
		}

	}
};

class CMainForm  //主界面
{
public:
	void SetProgressBar(ProgressBar* progressBar) { this->m_progressBar = progressBar;}
	ProgressBar* m_progressBar;
	void BottomClick()
	{
		CFileSplitter splitter(m_progressBar);
		splitter.SplitFile("file path");
	}
};

int main() //调用
{
	ProgressBar* progressBar = new ProgressBar;
	CMainForm main;
	main.SetProgressBar(progressBar);
	main.BottomClick();
	return 0;
}

//打印
CFileSplitter::SplitFile
hello
MainForm进度=0
MainForm进度=1
MainForm进度=2
MainForm进度=3
MainForm进度=4

需求更改

(写一个文件分割器,把一个大文件分割成五个小文件,并且显示进度。)不仅要mainform显示进度条,cmd也要显示进度,mainform从1递增,cmd的进度从1开始累加上次的值。

设计一更改版本

#include "stdafx.h"
#include <iostream>
using namespace std;
class ProgressBar  //进度
{
public:
	ProgressBar(){ m_progress = 0; }
	int m_progress;
	void SetProgress(int i) { this->m_progress = i;}
	int GetProgress() { std::cout << "MainForm进度2=" << this->m_progress << std::endl; return this->m_progress; };
};

class ProgressBar2  //改变1
{
public:
	ProgressBar2(){ m_progress = 0; }
	int m_progress;
	void SetProgress(int i) { this->m_progress += i;}
	int GetProgress() { std::cout << "Cmd进度2=" <<this->m_progress << std::endl; return this->m_progress; };
};

class CFileSplitter 
{
public:
	CFileSplitter(ProgressBar* progressBar, ProgressBar2* progressBar2)
	{ 
		this->m_progressBar = progressBar;
		m_progressBar2  = progressBar2;
	} //改变6
	ProgressBar* m_progressBar;
	ProgressBar2* m_progressBar2;
	void SplitFile(string vName)
	{ 
		std::cout << __FUNCTION__ << std::endl;
		for (int i = 0; i < 5; i++)
		{
			m_progressBar->SetProgress(i);
			m_progressBar2->SetProgress(i);		
			m_progressBar->GetProgress();
			m_progressBar2->GetProgress();
		}

	}
};

class CCmd  //改变2
{
public:
	void SetProgressBar(ProgressBar2* progressBar) { this->m_progressBar = progressBar;}
	ProgressBar2* m_progressBar;
};

class CMainForm
{
public:
	void SetProgressBar(ProgressBar* progressBar) { this->m_progressBar = progressBar;}//改变32
	void SetProgressBar2(ProgressBar2* progressBar) { this->m_progressBar2 = progressBar;}
	ProgressBar* m_progressBar;
	ProgressBar2* m_progressBar2; //改变4
	void BottomClick()
	{
		CFileSplitter splitter(m_progressBar, m_progressBar2); //改变5
		splitter.SplitFile("file path");
	}
};

int main()
{
	ProgressBar* progressBar = new ProgressBar;
	ProgressBar2* progressBar2 = new ProgressBar2;
	CMainForm main;
	main.SetProgressBar(progressBar);
	main.SetProgressBar2(progressBar2);
	main.BottomClick();
	return 0;
}
//打印
CFileSplitter::SplitFile
MainForm进度2=0
Cmd进度2=0
MainForm进度2=1
Cmd进度2=1
MainForm进度2=2
Cmd进度2=3
MainForm进度2=3
Cmd进度2=6
MainForm进度2=4
Cmd进度2=10

违反原则

1.59行违反了原则一,依赖倒置原则,要面向接口而不是实现

	ProgressBar* m_progressBar;
	ProgressBar2* m_progressBar2; //改变4

设计二

设计二更改版本

#include <iostream>
#include <list>
using namespace std;
class IProgessBar 
{
public:
	IProgessBar(){ m_progress = 0; }
	virtual ~IProgessBar() {}

	int m_progress;
	virtual void SetProgress(int i) = 0;
	virtual int GetProgress() = 0;
};

class ProgressBar : public IProgessBar  //进度
{
public:
	void SetProgress(int i) { this->m_progress = i;}
	int GetProgress() { std::cout << "MainForm进度=" << this->m_progress << std::endl;return this->m_progress; };
};

class ProgressBar2 : public IProgessBar  //改变1
{
public:
	void SetProgress(int i) { this->m_progress += i;}
	int GetProgress() { std::cout << "Cmd进度=" << this->m_progress << std::endl;return this->m_progress; };
};

class CFileSplitter 
{
public:
	CFileSplitter(){} 
	void AddList(IProgessBar *progress) { m_progressBarList.push_back(progress); }
	void RemoveList(IProgessBar *progress) { m_progressBarList.remove(progress); }
	list<IProgessBar*> m_progressBarList;
	void SplitFile(string vName)
	{ 
		std::cout << __FUNCTION__ << std::endl;
		for (int i = 0; i < 5; i++)
		{
			for (list<IProgessBar*>::iterator ite = m_progressBarList.begin(); ite != m_progressBarList.end(); ite++)
			{
				(*ite)->SetProgress(i);
				(*ite)->GetProgress();
			}
		}
		
	}
};

class CCmd  //改变2
{
public:
	void SetProgressBar(ProgressBar2* progressBar) { this->m_progressBar = progressBar;}
	ProgressBar2* m_progressBar;
};

class CMainForm
{
public:
	void SetProgressBar(ProgressBar* progressBar) { this->m_progressBar = progressBar;}//改变32
	void SetProgressBar2(ProgressBar2* progressBar) { this->m_progressBar2 = progressBar;}
	ProgressBar* m_progressBar;
	ProgressBar2* m_progressBar2; //改变4
	void BottomClick()
	{
		CFileSplitter splitter; //改变5
		splitter.AddList(m_progressBar);
		splitter.AddList(m_progressBar2);
		splitter.SplitFile("file path");	
	}
};

int main()
{
	ProgressBar* progressBar = new ProgressBar;
	ProgressBar2* progressBar2 = new ProgressBar2;
	CMainForm main;
	main.SetProgressBar(progressBar);
	main.SetProgressBar2(progressBar2);
	main.BottomClick();
	return 0;
}
//打印
CFileSplitter::SplitFile
MainForm进度=0
Cmd进度=0
MainForm进度=1
Cmd进度=1
MainForm进度=2
Cmd进度=3
MainForm进度=3
Cmd进度=6
MainForm进度=4
Cmd进度=10

设计二比设计一区别

统一起来规划,和单一规划区别

模式定义

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

模式结构

在这里插入图片描述

要点总结

松耦合-只有添加和广播,删除

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值