//
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