jeudi 23 juin 2016

observer design pattern class issue

I was trying the observer design pattern to understand, the text book example looks simple and understandable. But when we actually implement the problem shows up for ex: when update() of individual class get invoked in for loop, the function may not be simple printf() statement instead it mostly will have criticle sections which is protected with mutex.

i.e, assume modified update function in class DivObserver, in the below text book example how do you solve the problem of not getting blocked by this update() function when executing forloop ?

  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);
 }

Aucun commentaire:

Enregistrer un commentaire