观察者模式用于通知功能,在实际实现中,很少有分类可能在通知函数中具有阻止调用。基本上我的问题是,如何避免通知功能被阻止。因为如果由于一个类而被阻止,则它会阻止其他所有调用。如下面的update()函数示例中的示例,在类divobserver中阻止了一个阻塞。
从原始类中修改了下面的类别,以显示一个类:
class DivObserver: public Observer {
public:
DivObserver(Subject *mod, int div): Observer(mod, div){}
void update()
{
pthread_mutex_lock();
/*blocking statement call*/
pthread_mutex_unlock();
}
};
-----------------------------------text book example--------------------- ---------------
#include <iostream>
#include <vector>
using namespace std;
class Subject {
// 1. "independent" functionality
vector < class Observer * > views; // 3. Coupled only to "interface"
int value;
public:
void attach(Observer *obs)
{
views.push_back(obs);
}
void setVal(int val)
{
value = val;
notify();
}
int getVal() {
return value;
}
void notify();
};
class Observer {
// 2. "dependent" functionality
Subject *model;
int denom;
public:
Observer(Subject *mod, int div) {
model = mod;
denom = div;
// 4. Observers register themselves with the Subject
model->attach(this);
}
virtual void update() = 0;
protected:
Subject *getSubject() {
return model;
}
int getDivisor() {
return denom;
}
};
void Subject::notify() {
// 5. Publisher broadcasts
for (int i = 0; i < views.size(); i++)
views[i]->update();
}
class DivObserver: public Observer {
public:
DivObserver(Subject *mod, int div): Observer(mod, div){}
void update() {
// 6. "Pull" information of interest
int v = getSubject()->getVal(), d = getDivisor();
cout << v << " div " << d << " is " << v / d << 'n';
}
};
class ModObserver: public Observer {
public:
ModObserver(Subject *mod, int div): Observer(mod, div){}
void update() {
int v = getSubject()->getVal(), d = getDivisor();
cout << v << " mod " << d << " is " << v % d << 'n';
}
};
int main() {
Subject subj;
DivObserver divObs1(&subj, 4); // 7. Client configures the number and
DivObserver divObs2(&subj, 3); // type of Observers
ModObserver modObs3(&subj, 3);
subj.setVal(14);
}
观察者模式正在解决一个问题,以创建几个全新的问题。对于几乎每个模式来说,这是如此典型。
诀窍是知道如何控制模式的行为。在观察者的情况下,您获得的好处是,您可以有效地回电许多其他对象,而无需依赖于它们的类型。这是观察者的好部分。不好的部分是,一旦您回电,您就会受到呼叫的对象的摆布。
开发人员经常忘记的观察者的另一个问题是,订户必须在计划死亡之前取消订阅。否则,可观察的对象将在带有垃圾收集的系统中保持其活力。在具有显式内存DEADLOCATION的系统中,可观察的对象将具有悬空的参考,这甚至更糟。
在这两个问题中没有很好的方法。它们是观察者模式的签名,就像通知概念一样。我们可以说,即使有超时等,也可以将实施变为异步版本。但这将超出可观察模式的范围,这将是完全不同的设计。
底线:是的,如果观察者对象块,则可观察到的对象被阻止,并且对可观察对象的呼叫也被阻止了。