目录 1.动机 2.模式定义 3.要点总结 4.代码感受 1.代码一 1.FileSplitter.cpp 2.MainForm.cpp 2.代码二 1.FileSplitter.cpp 2.MainForm.cpp
1.动机
在软件构建过程中,需要为某些对象建立一种“通知依赖关系 ” 一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知 如果这样的依赖关系过于紧密, 将使软件不能很好地抵御变化 使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合
2.模式定义
定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新 结构
3.要点总结
使用面向对象的抽象,Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达致松耦合 目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播 观察者自己决定是否需要订阅通知,目标对象对此一无所知 Observer模式是基于事件的UI框架中非常常用的设计模式,也是MVC模式的一个重要组成部分
4.代码感受
1.代码一
1.FileSplitter.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 ( ) { for ( int i = 0 ; i < m_fileNumber; i++ ) { float progressValue = ( i + 1 ) / m_fileNumber; m_progressBar-> setValue ( progressValue) ; } }
} ;
2.MainForm.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 ( ) ; }
} ;
2.代码二
1.FileSplitter.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 ( ) { for ( int i = 0 ; i < m_fileNumber; i++ ) { float progressValue = ( i + 1 ) / m_fileNumber; 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++ ; } }
} ;
2.MainForm.cpp
class ConsoleNotifier : public IProgress
{
public : virtual void DoProgress ( float value) { cout << "." ; }
} ;
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 ( ) ) ; FileSplitter splitter ( filePath, number) ; ConsoleNotifier cn; splitter. addIProgress ( this ) ; splitter. addIProgress ( & cn) ; splitter. split ( ) ; } virtual void DoProgress ( float value) { progressBar-> setValue ( value) ; }
} ;