//
Purpose.  Mediator
//
//
Discussion.  On the left: Node objs  #include <iostream.h>
// interact
directly with each other,
// recursion is required, removing a    class Node {
// Node is hard, and it
is not possi-   public:
// ble to
remove the first node.  On       Node( int v ) { val_ = v; }
// the
right: a "mediating" List class    
int getVal()  { return val_;
}
// focuses and simplifies all the ad-  
private:
// ministrative responsibilities, and      int 
val_;
// the recursion (which does not scale  };
// up well) has been
eliminated.
                                        class List {
#include
<iostream.h>                  
public:
                                           List() {
class Node
{                                  for
(int i=0; i < 10; i++)
public:                                          arr_[i] = 0;
   Node( int v, Node* n ) {                      num_ = 0;
      val_ = v;                            }
      next_ = n;                           void addNode( Node* n ) {
   }        
                                 arr_[num_++] = n;
   void traverse() {                       }
     
cout << val_ << " 
";                void
traverse() {
      if (next_)                              for (int i=0; i
< num_; i++)
        
next_->traverse();                      cout << arr_[i]->getVal()
      else                                          << "  ";
         cout << endl;                        cout << endl;
   }                                       }
   void removeNode( int v ) {              void removeNode( int v ) {
      Node*  ptr = (Node*)
1;                 int  i, j;
      removeNode_( v, &ptr );                 for (i=0; i < num_; i++)
   }                                             if
(arr_[i]->getVal() == v)
private:                                         {
   int   
val_;                                     for (j=i; j < num_;
j++)
   Node*  next_;                                       arr_[j] = arr_[j+1];
   void removeNode_(int v, Node** n) {              num_--;
      if (val_ == v)                                break;
         *n = next_;                             }
      else                                 }
      {                                 private:
         next_->removeNode_( v, n );       Node* 
arr_[10];
         if (*n !=
(Node*) 1)              int    num_;
         {                              };
            next_ = *n;
            *n = (Node*) 1;             void main( void )
         }                              {
      }                                    List  lst;
   }                                       Node  one( 11 ), 
two( 22 );
};                                         Node  thr( 33 ), 
fou( 44 );
                                           lst.addNode( &one
);
void main( void )                          lst.addNode( &two );
{                                         
lst.addNode( &thr );
  
Node  fou( 44, 0 );                     lst.addNode( &fou
);
   Node  thr( 33, &fou );                  lst.traverse();
   Node 
two( 22, &thr );                  lst.removeNode( 44 );
   Node 
one( 11, &two );                 
lst.traverse();
  
one.traverse();                        
lst.removeNode( 11 );
  
one.removeNode( 44 );                  
lst.traverse();
  
one.traverse();                     
}
   one.removeNode( 22
);
   one.traverse();                      // 11  22 
33  44
}                                       //
11  22 
33
                                        // 22  33
// 11  22  33  44
// 11  22  33
// 11  33
// Purpose.  Mediator design pattern demo.
// 
//
Discussion.  Though partitioning a
system into many objects generally
// enhances reusability, proliferating
interconnections tend to reduce it
// again.  You can avoid this problem by capsulating the
interconnections
// (i.e. the collective behavior) in a separate
"mediator" object.  A
//
mediator is responsible for controlling and coordinating the
//
interactions of a group of objects.  In
this example, the dialog box
// object is functioning as the
mediator.  Child widgets of the dialog
box
// do not know, or care, who their siblings are.  Whenever a simulated
// user
interaction occurs in a child widget [Widget::changed()], the
// widget
does nothing except "delegate" that event to its parent dialog
//
box [_mediator->widgetChanged( this )].
//
FileSelectionDialog::widgetChanged() encapsulates all collective
//
behavior for the dialog box (it serves as the hub of communication).
//
The user may choose to "interact" with a simulated: filter edit
field,
// directories list, files list, or selection edit field.
#include
<iostream.h>
class FileSelectionDialog;
class
Widget {
public:
      Widget(
FileSelectionDialog* mediator, char* name ) {
            _mediator = mediator;
            strcpy( _name, name); }
      virtual void changed();
      virtual
void updateWidget() = 0;
      virtual
void queryWidget() = 0;
protected:
      char                 _name[20];
private:
      FileSelectionDialog* _mediator;
};
class
List : public Widget {
public:
      List(
FileSelectionDialog* dir, char* name ) : Widget( dir, name ) { }
    void queryWidget()  { cout << "   " << _name << " list
queried" << endl; }
      void
updateWidget() { cout << "  
" << _name << " list updated" << endl;
}
};
class Edit : public Widget {
public:
    Edit( FileSelectionDialog* dir, char* name
): Widget( dir, name ) { }
    void
queryWidget()  { cout <<
"   " << _name <<
" edit queried" << endl; }
    void updateWidget() { cout << "   " << _name << " edit
updated" << endl; }
};
class
FileSelectionDialog {
public:
      enum
Widgets { FilterEdit, DirList, FileList, SelectionEdit };
      FileSelectionDialog() {
            _components[FilterEdit]    = new Edit( this, "filter"
);
            _components[DirList]       = new List( this, "dir"
);
            _components[FileList]      = new List( this, "file"
);
            _components[SelectionEdit]
= new Edit( this, "selection" ); }
      virtual ~FileSelectionDialog();
      void handleEvent( int which ) {
            _components[which]->changed(); }
      virtual void widgetChanged( Widget*
theChangedWidget ) {
            if
(theChangedWidget == _components[FilterEdit] ) {
                  _components[FilterEdit]->    queryWidget();
                  _components[DirList]->       updateWidget();
                  _components[FileList]->      updateWidget();
                  _components[SelectionEdit]->
updateWidget(); }
            else if
(theChangedWidget == _components[DirList] ) {
                  _components[DirList]->       queryWidget();
                  _components[FileList]->      updateWidget();
                  _components[FilterEdit]->    updateWidget();
                  _components[SelectionEdit]->
updateWidget(); }
            else if
(theChangedWidget == _components[FileList] ) {
                  _components[FileList]->      queryWidget();
                  _components[SelectionEdit]->
updateWidget(); }
            else if
(theChangedWidget == _components[SelectionEdit] ) {
                  _components[SelectionEdit]->
queryWidget();
                  cout
<< "   file opened"
<< endl; } }
private:
      Widget*
_components[4];
};
FileSelectionDialog::~FileSelectionDialog()
{
      for (int i=0; i < 3;
i++)
            delete
_components[i]; }
void Widget::changed() {
      _mediator->widgetChanged( this );
}
void main() {
      FileSelectionDialog
fileDialog;
      int                 i;
      cout << "Exit[0], Filter[1], Dir[2],
File[3], Selection[4]: ";
      cin
>> i;
      while
(i)
      {
            fileDialog.handleEvent( i-1 );
            cout << "Exit[0],
Filter[1], Dir[2], File[3], Selection[4]: ";
            cin >> i;
      }
}
//
Exit[0], Filter[1], Dir[2], File[3], Selection[4]: 1
//    filter edit queried
//    dir list updated
//    file list updated
//    selection edit updated
// Exit[0],
Filter[1], Dir[2], File[3], Selection[4]: 2
//    dir list queried
//   
file list updated
//   
filter edit updated
//   
selection edit updated
// Exit[0], Filter[1], Dir[2], File[3],
Selection[4]: 3
//    file list
queried
//    selection edit
updated
// Exit[0], Filter[1], Dir[2], File[3], Selection[4]: 4
//    selection edit queried
//    file opened
// Exit[0], Filter[1],
Dir[2], File[3], Selection[4]: 3
//   
file list queried
//   
selection edit updated