本文讲述了组件协作模式中的观察者模式,介绍了观察者模式的动机、定义、结构、代码实例,最后进行了总结。
再次感谢GeekBand的李建忠老师、GOF等前辈
1. “组件协作”模式:
- 现代软件专业分工之后的第一个结果是“框架与应用程序的划分”,“组件协作”模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用的模式。
- 典型模式
- Template Method
- Strategy
- Observer / Event 观察者模式
2. 动机(Motivation)
- 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系” ——一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,使软件不能很好地抵御变化。
- 使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。
3. 代码实例
MainForm1.cpp
与FileSplitter1.cpp
程序实现了文件的切分与进度更新,前者实现了简单的Window窗口程序,窗口内含有文件路径文本框、文件切分个数文本框和任务进度条,后者实现了文件的读取、切分以及进度条更新操作。
// MainForm1.cpp
// Window窗口代码
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();
}
};
// 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); // 更新进度条
}
}
};
在对软件进行重构时,不要先去想可以使用那种设计模式,而是先考虑违背了那些设计原则。上述代码显然违背了“依赖倒置原则<