110 likes | 267 Views
Behavioral Pattern: Mediator. Chapter 5 – Page 169.
E N D
Behavioral Pattern: Mediator Chapter 5 – Page 169 When a program is made up of several classes, the logic and computation is divided among these classes. However, as more classes are developed, the problem of communication between them becomes more complex. This makes the program harder to read and to maintain. Further, it can become difficult to change the program, since any change may affect code in several other classes. The Mediator Pattern addresses this problem by promoting looser coupling between the classes. The Mediator is the only class that has detailed knowledge of the methods of other classes. Classes inform the Mediator when changes occur and the Mediator passes them on to any other classes that need to be informed.
The Mediator Pattern Chapter 5 – Page 170 The Mediator provides the interface for communicating with Colleague objects. • The ConcreteMediator knows and maintains its Colleagues, and implements cooperative behavior by coordinating the Colleague objects. • Each Colleague class knows its Mediator object, communicating with it whenever it would have otherwise communicated with another Colleague.
Non-Software Example: ATC Chapter 5 – Page 171 The pilots of the planes (the Colleagues) approaching or departing the terminal area communicate with the tower (the Mediator) rather than explicitly communicating with one another. The constraints on who can take off or land are enforced by the tower. Notice that the tower does not control the whole flight. It exists only to enforce constraints in the terminal area.
Software Example: Label Switched Paths Chapter 5 – Page 172 Consider a complex managed network, offering a variety of services, including Internet telephony and data applications (email, server access, application access, etc.). A label switched path (LSP) is a forwarding path for traffic. The advantage of using LSPs rather than merely relying on IP forwarding is that LSPs provide more detailed control of the network. Path and Quality-of-Service (QoS) configuration data (the Colleagues) is dynamically maintained by a connection director (the Mediator) who continually adjusts and reconfigures the LSP.
LSP Mediator Code in C++ Chapter 5 – Page 173 #include <iostream> using namespace std; class Widget; classConnectionDirector { public: explicitConnectionDirector() {} virtual ~ConnectionDirector() {} virtual voidWidgetChanged(Widget*) = 0; protected: ConnectionDirector(int); virtual void CreateWidgets() = 0; }; class Widget { public: explicit Widget(ConnectionDirector* aConnDirector) { director = aConnDirector; } virtual void Changed() { director->WidgetChanged(this); } protected: ConnectionDirector* director; };
Chapter 5 – Page 174 classPathWidget : public Widget { public: explicitPathWidget(ConnectionDirector* theDirector) : Widget(theDirector) {} virtual ~PathWidget() {} voidCreateInitialPath(char* newPath) { pathDetails = newPath; cout << "Initial path setting: " << pathDetails << endl; } voidgetNewPath() { cout << "The PathWidget path is: " << pathDetails << endl; } voidChangePath(char* newPath) { pathDetails = newPath; cout << "The updated PathWidget path is: " << pathDetails << endl; Changed(); } private: char* pathDetails; };
Chapter 5 – Page 175 classQosWidget : public Widget { public: explicitQosWidget(ConnectionDirector* theDirector) : Widget(theDirector) {} virtual ~QosWidget() {} voidCreateInitialQoS(char* initialQoSDetails) { QoSDetails = initialQoSDetails; cout << "Initial QoS setting: " << QoSDetails << endl; } voidgetNewQoS() { cout << "The QosWidget details are: " << QoSDetails << endl; } voidChangeQoSDetails(char* newQoSDetails) { QoSDetails = newQoSDetails; cout << "The updated QosWidgetQoS details are " << QoSDetails << endl; Changed(); } private: char* QoSDetails; };
Chapter 5 – Page 176 classLspDirector : publicConnectionDirector { public: explicitLspDirector(intanLspId) {lspId = anLspId; } virtual ~LspDirector() {} virtual voidWidgetChanged(Widget* imAChangedWidget) { if (imAChangedWidget == lspPath) // Change the path used by the LSP cout << "Director informed of change to LSP Path" << endl; else if (imAChangedWidget == qosDescriptor) // Change the Qos resources used by the LSP cout << "Director informed of change to QoS Resources" << endl; } virtual void CreateWidgets() { lspPath = newPathWidget(this); lspPath->CreateInitialPath("R2R3R4R5"); qosDescriptor = newQosWidget(this); qosDescriptor->CreateInitialQoS("Assured Forwarding"); } voidChangePath(char* newPath) { lspPath->ChangePath(newPath); } voidChangeQoSDetails(char* newQoS) { qosDescriptor->ChangeQoSDetails(newQoS); } private: intlspId; PathWidget* lspPath; QosWidget* qosDescriptor; };
Chapter 5 – Page 177 void main() { LspDirector* anExampleMediator = newLspDirector(555); // Create several widgets for the LSP anExampleMediator->CreateWidgets(); anExampleMediator->ChangePath("R2R6R5"); anExampleMediator->ChangeQoSDetails("Expedited Forwarding"); deleteanExampleMediator; return; }
Mediator Pattern Advantages Chapter 5 – Page 178 • The Mediator makes loose coupling possible between objects in a program. It also localizes the behavior that otherwise would be distributed among several objects. • The Mediator approach makes it possible to add new Colleagues to a system without having to change any other part of the program. In addition, the behavior of the program can be changed by simply changing or subclassing the Mediator. • The Mediator can become monolithic in complexity, making it hard to change and maintain. This situation can sometimes be improved by revising the responsibilities given to the Mediator. Each object should carry out its own tasks and the Mediator should only manage the interaction between objects.