定义:
对象间的一种多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖它的对象都得到通知并自动更新。
class FileSplitter//分割实现类
{
string m_filePath;
int m_fileNumber;
vector<IProgress*> m_iprogress;//抽象通知机制 支持多个观察者
public:
FileSplitter(const string& filePath,int fileNumber):
m_filePath(filepath),m_fileNumber(fileNumber){}
void add_IProgress(IProgress* iprogress)//添加观察者
{
m_iprogress.push_back(iprogress);
}
void remove_IProgress(IProgress* iprogress)//删除观察者
{
m_iprogress.remove(iprogress);
}
void split(){
//1.读取大文件
//2.分批次向小文件写入
for(int i=0;i<m_fileNumber;i++){
....
float progressValue=(i+1)/m_fileNumber;//状态改变
ongress(progressValue);//给观察者发送通知
}
}
protected:
void onprogress(float value)
{
for(auto it=m_iprogress.begin();it!=m_iprogress.end();it++)
(*it)->Doprogress(value);//观察者自动更新
}
};
class IProgress{
public: virtual void Doprogress(float value)=0;
virtual ~IProgress(){}
};
//文件分割
class MainForm:public Form,public IProgress
{
TextBox* txtFilePath;
TextBox* txtFileNumber;
ProgressBar* progressBar;
public:
void Button_click()
{
string filepath=txtFilePath->getText();
int number=atoi(txtFileNumber->getText().c_str());
FileSplitter splitter(filePath,number,this);//实例化分割实现类对象
splitter.add_IProgress(this);//订阅通知
splitter.add_IProgress(&xx);//订阅通知
splitter.split();
}
virtual void Doprogress(float value)
{progressBar->setValue(value);}//设置进度条(重写 IProgress类中Doprogress方法)
};
//class consolenotifier:public IProgress
Go语言版本
package observer
import "fmt"
//观察者结构体
type Subject struct {
observers []Observer
context string
}
//创建观察者数组
func NewSubject() *Subject {
return &Subject{
observers: make([]Observer, 0),
}
}
//添加观察者到观察者数组中
func (s *Subject) Attach(o Observer) {
s.observers = append(s.observers, o)
}
//通知观察者进行更新
func (s *Subject) notify() {
for _, o := range s.observers {
o.Update(s)
}
}
//更新发布内容
func (s *Subject) UpdateContext(context string) {
s.context = context
s.notify()
}
//update函数接口
type Observer interface {
Update(*Subject)
}
//订阅者结构体
type Reader struct {
name string
}
func NewReader(name string) *Reader {
return &Reader{
name: name,
}
}
//具体实现的更新方法
func (r *Reader) Update(s *Subject) {
fmt.Printf("%s receive %s\n", r.name, s.context)
}
//测试代码
package observer
func ExampleObserver() {
subject := NewSubject()
reader1 := NewReader("reader1")
reader2 := NewReader("reader2")
reader3 := NewReader("reader3")
subject.Attach(reader1)
subject.Attach(reader2)
subject.Attach(reader3)
subject.UpdateContext("observer mode")
// Output:
// reader1 receive observer mode
// reader2 receive observer mode
// reader3 receive observer mode
}
红色:稳定部分 蓝色:不稳定部分
Observer:Iprogress
update:Doprogress
Subject:
Attach:add_progress
Dettach:remove_progress
notify:onprogress
ConcreteSubject:Filesplitter