UMBC Some Additional Patterns CMSC 432
UMBC More Patterns2 Introduction Over the next few lectures we’ll have an introduction to a number of patterns –Façade - Structural Pattern –Mediator - Behavioral Pattern –Singleton – Creational Pattern Have an Introduction to UML
UMBC More Patterns3 Sources and References The Best Source for Design Patterns is –Design Patterns - Elements of Reusable Object- Oriented Software, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison Wesley This lecture comes almost exclusively from that excellent text Good Notation Guide for UML is availableGood Notation Guide
UMBC More Patterns4 Categories of Patterns Creational –deal with the process of object creation. Structural –deal with the composition of classes or objects Behavioral – deal with the ways in which classes interact
UMBC More Patterns5 Wrap Up of Façade Pattern Central Ideas –What is the purpose of a Façade Pattern –What is its central virtue? Mediator is similar to a Façade in that it abstracts functionality of existing classes –The classes that embody a subsystem hidden by a Façade pattern do not know about the Facade
UML in a Nutshell whole part realizes (uses)
UMBC More Patterns7 UML in a Nutshell Class Interaction Diagrams Obj1 Obj4Obj3Obj2 Time
UMBC More Patterns8 Mediator An Object Behavioral Pattern Similar in focus to the façade object Intent –Define an object that encapsulates how a set of objects interact –Mediator promotes loose coupling by keeping objects from referring to each other explicitly –Lets objects vary their interaction independently
UMBC More Patterns9 Mediator Motivation OO design encourages the distribution of behavior among objects Such distribution when carried to an extreme can result in an object structure with many connections between objects In the extreme every object needs to know about every other
UMBC More Patterns10 Mediator Motivation continued Partitioning a system into many objects generally enhances reusability Each object is small and has a specific if limited purpose Proliferating interconnections between objects, on the other hand tends to reduce reusability System behaves as if it were monolithic
UMBC More Patterns11 Mediator Motivation - Example As an example consider the implementation of dialog boxes in a GUI A dialog box uses a window to present a collection of components (called widgets)
UMBC More Patterns12 Diagram
UMBC More Patterns13 Mediator example Typically there are dependencies between the components in the dialog Examples – a button gets disabled when an entry field is empty –selecting an entry in a list of choices from a list box might change the contents of an entry field –typing text into the entry field might automatically select one or more entries in a list box –selecting entries might gray out buttons
UMBC More Patterns14 Dialog Box Example Analysis On the surface it might seem that the behavior of each object is intertwined The more intertwined the behavior the harder the system would be to change or enhance The more intertwined the behavior the harder the code would be to reuse
UMBC More Patterns15 Dialog Box Example Analysis Continued Different dialog boxes will have different dependencies between components with a GUI So even though dialogs display the same kinds of components they simply can’t reuse stock widget classes easily Customizing them individually by subclassing will be tedious since many classes can be involved
UMBC More Patterns16 Answer to the dilemma You can avoid many of these problems by having a single class mediate the widget interaction This is the central idea behind the mediator pattern Individual widgets need only know about the mediator Mediator knows about and coordinates the complex behavior
UMBC More Patterns17 FontDialogDirector Example
UMBC More Patterns18 FontDialogDirector Example The central idea is that the mediator ties together all the objects but any individual object needs to know only about itself and the mediator The FontDialogDirector can be the mediator between the widgets in the dialog box
UMBC More Patterns19 Mediator interaction The mediator acts as a hub of communications for the widgets Lets look at a specific example using the FontDialogDirector Note that all interactions are mediated through the FontDialogDirector
UMBC More Patterns20 Interaction Diagram
UMBC More Patterns21 An Example Here are the events that transpire when a list box’s selection passes to an entry field –the list box tells its director that it has changed –the director gets the selection from the list box –the director passes the selection to the entry field –now that the entry field contains some text, the director enable button(s) for initiating an action
UMBC More Patterns22 The Interaction Note that the director mediates between the list box and the entry field Widgets (components) communicate with each other only indirectly through the mediator Widgets don’t have to know about each other all they know is the director Because behavior is localized in one class it can be changed or replaced by extending or replacing that single class
UMBC More Patterns23 The FontDialogDirector Integration Diagram Inheritance
UMBC More Patterns24 The FontDialogDirector Integration Here is how the FontDialogDirector abstraction can be integrated into a class library –DialogDirector is an abstract class that defines the overall behavior of a dialog –Clients call the ShowDialog operation to display the dialog
UMBC More Patterns25 The FontDialogDirector Integration(Continued) –CreateWidgets is an abstract operation for creating the widgets in a dialog –WidgetChanged is another abstract operation that informs the Director of a Widget state change –Note that each DialogDirector subclass must override CreateWidgets and WidgetChanged
UMBC More Patterns26 Applicability of the Mediator Pattern Use the Mediator Pattern when –a set of objects communicate in well defined but complex ways –reusing an object is difficult because it refers to and communicates with many other objects –a behavior that’s distributed between several classes should be customizable without a lot of subclassing
UMBC More Patterns27 Class Structure Diagram The structure of the Mediator pattern as a class diagram looks this
UMBC More Patterns28 Instance Structure Diagram The structure of the Mediator pattern as a instance diagram looks this
UMBC More Patterns29 Participants Mediator (DialogDirector) –defines an interface for communication with Colleague objects. Concrete Mediator (FontDialogDirector) –implements cooperative behavior by coordinating Colleague objects –knows and maintains its colleagues
UMBC More Patterns30 Participants Continued Colleague Classes (ListBox, EntryField, …) –each colleague class knows about its Mediator object –each colleague communicates with its mediator whenever it would have otherwise communicated directly with another colleague
UMBC More Patterns31 Collaborations Colleagues send and receive requests from a Mediator object The Mediator implements the cooperative behavior by routing requests between appropriate colleagues
UMBC More Patterns32 Mediator Pattern Consequences The Mediator pattern has the following benefits and drawbacks: –It limits subclassing. A mediator localizes behavior that otherwise would be distributed throughout several objects changing the behavior of a system implies subclassing the Mediator only Colleague classes can be reused as is
UMBC More Patterns33 Consequences Continued Colleagues may be decoupled –A Mediator promotes loose coupling –You can vary and reuse Colleague and Mediator classes independently It simplifies object protocols –A mediator replaces many to many interactions with one to many interactions between the mediator and its colleagues –One to many relationships are easier to understand, encode, amend and reuse
UMBC More Patterns34 More Consequences The Mediator pattern abstracts how objects cooperate –making mediation an independent concept and encapsulating it in an object lets you focus on how objects interact apart from their individual behavior –doing so can help clarify how objects interact in a system
UMBC More Patterns35 The Drawback of the Mediator Pattern The Use of the Mediator Pattern centralizes control –The pattern trades complexity of interaction for complexity in the Mediator itself –Because a Mediator encapsulates protocols, it can become more complex than any individual colleague –This, if unchecked, make the mediator itself a monolith that’s hard to maintain
UMBC More Patterns36 Implementation Issues You can omit the abstract Mediator class when colleagues work with only one mediator –The abstract coupling that the Mediator class provides lets colleagues work with different Mediator subclasses and vice versa
UMBC More Patterns37 More Implementation Issues Colleague-Mediator Communication –Colleagues have to communicate with their mediator when an event of interest occurs –Colleague classes acts as subjects sending notifications to the mediator whenever they change state –One approach is to have the colleague pass itself as an argument when communicating to the mediator - this is in effect a callback mechanism the mediator can easily identify and respond to the sender in this manner
UMBC More Patterns38 The Dialog Director Class Here is the code for the abstract DialogDirector class DialogDirector { public: virtual ~DialogDirector(); virtual void ShowDialog(); virtual void WidgetChanged(Widget*) = 0; protected: DialogDirector(); virtual void CreateWidgets() = 0; };
UMBC More Patterns39 The Widget Class class Widget { public: Widget(DialogDirector*); virtual void Changed(){ _director->WidgetChanged(this); } virtual void HandleMouseEvent(MouseEvent& e) = 0; //... private: DialogDirector* _director; };
UMBC More Patterns40 Notes Note that the constructor sets the DialogDirector Note that the changed method simply calls the WidgetChanged method of the director mediator –this happens on any significant event
UMBC More Patterns41 Subclasses of Dialog Director To use the pattern you must subclass the abstract DialogDirector class –the WidgetChanged method method needs to be overridden the widget passes a reference to itself as an argument to WidgetChanged to let the director identify the widget that changed DialogDirector subclasses also redefine the CreateWidgets pure virtual
UMBC More Patterns42 Widget Examples The ListBox, EntryField and Button classes are subclasses of Widget They are for specialized user interface components ListBox provides a GetSelection to get the current selection EntryField provides a SetText to put new text into an entry
UMBC More Patterns43 ListBox Code Example class ListBox :public Widget { public: ListBox(DialogDirector*); virtual const char GetSelection (); virtual void SetList(List listItems); virtual void HandleMouseEvent(MouseEvent& e); //... };
UMBC More Patterns44 EntryField Code Example class EntryField :public Widget { public: EntryField(DialogDirector*); virtual void SetText(const char* text ); virtual const char* GetList(); virtual void HandleMouseEvent(MouseEvent& e); //... };
UMBC More Patterns45 The Button Code Button is a simple widget that calls Changed whenever it is pressed - this happens in HandleMouse class Button :public Widget { public: Button(DialogDirector*); virtual void SetText(const char* text ); virtual const char* GetList(); virtual void HandleMouseEvent(MouseEvent& e){ // … Changed(); } //... };
UMBC More Patterns46 FontDialogDirector Example Code class FontDialogDirector :public DialogDirector { public: virtual ~FontDialogDirector(); FontDialogDirector(); virtual void WidgetChanged(Widget*); protected: virtual void CreateWidgets(); private: Button* _ok; Button* _cancel; ListBox* _fontList; EntryField* _fontName; }; FontDialogDirector class mediates widgets in the dialog box
UMBC More Patterns47 Creating a Dialog’s Elements virtual void FontDialogDirector::CreateWidgets() { _ok = newButton(this); _cancel = new Button(this); _fontList = new EntryField(this); _fontName = new EntryField(this); // fill the listBox with the available font names // assemble the widgets in the dialog }
UMBC More Patterns48 Widget changed WidgetChanged ensures that the widgets work together properly virtual void FontDialogDirector::WidgetChanged(Widget* theChangedWidget) { if (theChangedWidget ==_fontList) { _fontName->SetText(_fontList->GetSelection()) } else if (theChangedWidget ==_ok) { // apply font change and dismiss dialog } else if (theChangedWidget ==_cancel) { // dismiss dialog }