C++【设计模式】 | 【03 组件协作模式】Observer
文章目录
一、Observer
1、优点
2、适用场景

3、模板示例
#include <iostream>
#include <vector>
class Subject;
class Observer
{
public:
virtual ~Observer() {}
virtual int getState() = 0;
virtual void update( Subject *subject ) = 0;
};
class ConcreteObserver : public Observer
{
public:
ConcreteObserver( const int state ) :
observer_state( state ) {}
~ConcreteObserver() {}
int getState() { return observer_state; }
void update( Subject *subject );
private:
int observer_state;
};
class Subject
{
public:
virtual ~Subject() {}
void attach( Observer *observer );
void detach( const int index );
void notify()
{
for ( unsigned int i = 0; i < observers.size(); i++ )
{
observers.at( i )->update( this );
}
}
virtual int getState() = 0;
private:
std::vector<Observer*> observers;
};
class ConcreteSubject : public Subject
{
public:
~ConcreteSubject() {}
int getState() { return subject_state; }
void setState( const int s ) { subject_state = s; }
private:
int subject_state;
};
void ConcreteObserver::update( Subject *subject )
{
observer_state = subject->getState();
std::cout << "Observer state updated." << std::endl;
}
int main()
{
ConcreteObserver observer1( 1 );
ConcreteObserver observer2( 2 );
std::cout << "Observer 1 state: " << observer1.getState() << std::endl;
std::cout << "Observer 2 state: " << observer2.getState() << std::endl;
Subject *subject = new ConcreteSubject();
subject->attach( &observer1 );
subject->attach( &observer2 );
subject->setState( 10 );
subject->notify();
std::cout << "Observer 1 state: " << observer1.getState() << std::endl;
std::cout << "Observer 2 state: " << observer2.getState() << std::endl;
delete subject;
return 0;
}
4、实例
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 << ".";
}
};
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){s
}
void split(){
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++;
}
}
};