1、引言
- 观察者模式又称为发布定阅模式,在Qt里的信号槽机制就是很好的一个观察者模式的例子。在我的工程里也使用了一个观察者模式来实现多语言。当使用Qt的 desinger来设计界面时会自动生成一个ui的文件,这个文件里天生就给你加了一个函数:
retranslateUi()
这个函数就是用来做多语言处理的。对于不想使用Qt designer的,这个工作得自己来做了。
我们可以抽象一个所有要使用多语言的界面类(继承自QWidget),然后加上retranslateUi( ),当然有些业务逻辑的类也可能要多语言的需求而它们都继承自QObject,这个时也可以参考界面类,抽象一个基类出来并都有retranslateUi( )方法,然后把所有的需要有多语言翻译的Object都注册到一个类里,这个类挨个调用retranslateUi( )来实现多语言的切换。
2、定义
观察者模式定义对象之间的一种一对多的依赖关系,当一个对象的状态发生改变时所有依赖于它的对象都得到通知并更新自己。它属于一种行为模式。
3、UML图
4、C++实现
做为一个家长,你可能关心孩子当前的状态,你可以让他的状态都通知家里的每一个人。
4.1、 观察者实现
//前置申请主题
class subject;
//抽象的观察者
class observer
{
public:
observer(subject*);
virtual void notify()=0;
protected:
subject *sub; //我们要获取主题的状态
};
//具体的观察者
class concreteObserver : public observer
{
public:
concreteObserver(subject* ,string name);
void notify();
private:
string myName;//观察者名字
};
observer::observer(subject * s)
:sub(s)
{
}
concreteObserver::concreteObserver(subject * s, string name)
:observer(s)
,myName(name)
{
}
//通知具体的观察者
void concreteObserver::notify()
{
cout<<"i'm your "<< myName << ","<< " i already know your are :"<<sub->getState()<<endl;
}
4.2、主题实现
class subject
{
public:
//主题动态可以增加与减少观察都
void attach(observer*);
void detach(observer*);
//让观察者能得到主题的变化
string getState();
//改变主题的状态
void setState(string);
//通知所有在册的观察者
void notify();
private:
vector<observer*> vec;
string state;
};
void subject::attach(observer * o)
{
vec.push_back(o);
}
void subject::detach(observer * o)
{
for(vector<observer*>::iterator it = vec.begin();it != vec.end();it++)
{
if(*it == o) vec.erase(it);
}
}
string subject::getState()
{
return state;
}
void subject::setState(string s)
{
state = s;
}
void subject::notify()
{
for(unsigned int i = 0;i < vec.size();i++)
vec[i]->notify();
}
4.3、客户端实现
int main()
{
subject *s = new subject();
s->attach(new concreteObserver(s, "father"));
s->attach(new concreteObserver(s, "mother"));
s->attach(new concreteObserver(s, "grandPa"));
s->setState("go home");
s->notify();
s->setState("go to school");
s->notify();
return 0;
}
5、总结
- 一对多的关联关系
- 观察者和观察者没有紧密地耦合在一起