观察者设计模式类问题

时间:2016-06-23 19:03:56

标签: design-patterns

观察者模式用于通知功能,在实际实现中,很少有类可能在notify函数中有阻塞调用。基本上我的问题是,如何避免通知功能被阻止。因为如果它因一个类而被阻止,那么它会阻止所有其他的调用。如下面的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);
 }

1 个答案:

答案 0 :(得分:1)

观察者模式正在解决一个问题,而不是创造一些全新的问题。几乎每种模式都是如此典型。

诀窍是知道如何控制模式的行为。在Observer的情况下,您获得的好处是您可以有效地回拨许多其他对象,而不必依赖于它们的类型。关于观察者,这是很好的部分。不好的一面是,一旦你回电话,你就会受到你所呼唤的对象的支配。

开发人员经常忘记的关于Observer的另一个问题是订户在计划死之前必须取消订阅。否则,可观察对象将在具有垃圾收集的系统中保持活动状态。在具有显式内存释放的系统中,可观察对象将持有悬空引用,这更糟糕。

这两个问题没有好办法。它们是Observer模式的签名,与通知概念一样多。我们可以说有可能将实现转换为异步版本,即使有超时等等。但这将超出Observable模式的范围,这将是一个完全不同的设计。

底线:是的,如果观察者对象阻塞,则可观察对象被阻止,并且对可观察对象进行调用的客户端也被阻止。