 // Purpose.  Observer                   class Obs;
 //
 // Discussion.  On the left: Subject    class Subject {
 // has hard-wired the number and type   public:
 // of "dependent" objects, the compil-     Subject();
 // er must have the declaration of the     void attach( Obs* );
 // concrete Obs classes to compile         void setVal( int );
 // Subject's decl, the Obs classes ex-     int  getVal();
 // ercise no reuse of i/f or impl, and     void notify();
 // Subject "pushes" updates to the Obs  private:
 // objects.  On the right: Subject is      Obs*  obs_[10];
 // decoupled from the number, type,        int   num_, val_;
 // and declaration of concrete Obs      };
 // subclasses; the Obs objects accept
 // polymorphism; and Subject broad-     class Obs { public:
 // casts that a change has occurred        virtual void update() = 0;
 // followed by Obs objects requesting   protected:
 // just the info that they want.           Subject*  sub_;
                                            int       div_;
 class DivObs { public:                  };
    DivObs( int );                       class DivObs : public Obs { public:
    void update( int );                     DivObs( Subject*, int );
 private:                                   void update();
    int  div_;                           };
 };                                      class ModObs : public Obs { public:
 class ModObs { public:                     ModObs( Subject*, int );
    ModObs( int );                          void update();
    void update( int );                  };
 private:
    int  div_;                           Subject::Subject()     { num_ = 0; }
 };                                      int  Subject::getVal() { return val_; }
                                         void Subject::attach( Obs* o ) {
 class Subject {                            obs_[num_++] = o; }
 public:                                 void Subject::setVal( int v ) {
    Subject();                              val_ = v;   notify(); }
    void setVal( int );                  void Subject::notify() {
 private:                                   for (int i=0; i < num_; i++)
    int     val_;                              obs_[i]->update(); }
    DivObs  div_;
    ModObs  mod_;                        DivObs::DivObs( Subject* s, int d ) {
 };                                         sub_ = s;  div_ = d;
                                            sub_->attach( this ); }
 Subject::Subject() : div_(4), mod_(3)   void DivObs::update() {
    { }                                     int v = sub_->getVal();
 void Subject::setVal( int v ) {            cout << v << " div " << div_
    val_ = v;                                  << " is " << v / div_ << endl; }
    div_.update( val_ );                 ModObs::ModObs( Subject* s, int d ) {
    mod_.update( val_ ); }                  sub_ = s;  div_ = d;
                                            sub_->attach( this ); }
 DivObs::DivObs( int d ) { div_ = d; }   void ModObs::update() {
 void DivObs::update( int v ) {             int v = sub_->getVal();
    cout << v << " div " << div_            cout << v << " mod " << div_
       << " is " << v / div_ << endl; }        << " is " << v % div_ << endl; }
 ModObs::ModObs( int d ) { div_ = d; }
 void ModObs::update( int v ) {          void main( void )
    cout << v << " mod " << div_         {
       << " is " << v % div_ << endl; }     Subject  subj;
                                            DivObs   divObs1( &subj, 4 );
 void main( void )                          DivObs   divObs2( &subj, 3 );
 {                                          ModObs   modObs3( &subj, 3 );
    Subject  subj;                          subj.setVal( 14 );
    subj.setVal( 14 );                   }
 }
                                         // 14 div 4 is 3
 // 14 div 4 is 3                        // 14 div 3 is 4
 // 14 mod 3 is 2                        // 14 mod 3 is 2

