Post on 29-Aug-2021
1
Edgar Gabriel
COSC 3351
Software Design
Design Patterns
Behavioral Patterns (I)
Edgar Gabriel
Spring 2008
COSC 3351 – Software Design
Edgar Gabriel
Purpose
Creational Structural Behavioral
Scope Class Factory Method Adapter(class) Interpreter
Template Method
Object Abstract Factory Adapter(object) Chain of
Responsibility
Builder Bridge Command
Prototype Composite Iterator
Singleton Decorator Mediator
Façade Observer
Flyweight State
Proxy Strategy
Visitor
Memento
2
COSC 3351 – Software Design
Edgar Gabriel
Behavioral Patterns
• Deal with how classes and objects interact with each
other
– Sharing responsibilities between objects and classes
– characterize (complex) flow control between objects and classes
COSC 3351 – Software Design
Edgar Gabriel
Chain of Responsibility
• Intent: Avoid coupling the sender of a request to its
receiver by giving more than one object a chance to
handle the request
• Applicability: Use the Chain of Responsibility pattern if
– More than one object may handle the request, and the handler isn’t known a priori
– You want to issue a request to one of several objects without specifying the receiver explicitly.
– The set of objects that can handle a request should be specified dynamically
3
COSC 3351 – Software Design
Edgar Gabriel
Structure
<<interface>>
Handler
HandlerRequest()
ConcreteHandler1
HandlerRequest()
ConcreteHandler2
HandlerRequest()
Client
: Client : ConcreteHandler1 : ConcreteHandler2
HandleRequest()
HandleRequest()
COSC 3351 – Software Design
Edgar Gabriel
Participants
• Handler:
– defines an interface for handling requests
– (optionally) implements the successor link
• ConcreteHandler:
– Handles requests it is responsible fors
– Can access its successor
– If the ConcreteHandler can handle the request, it does so; else it forwards the request to its successor.
• Client: initiates the request to a ConcreteHandler
object on a chain
4
COSC 3351 – Software Design
Edgar Gabriel
Example
• A context sensitive Help System
– Depending on where you are in the GUI you get different screens when pressing on the help button
– If no specific help information exists for that part of the interface, the help system should display a general help message about the immediate context
– Problem: the object that ultimately provides the help information is unknown to the object (i.e. the button) that initiates the help request.
-> Decouples sender and receiver
COSC 3351 – Software Design
Edgar Gabriel
typedef int Topic;
const Topic NO_HELP_TOPIC = -1;
class HelpHandler {
public:
HelpHandler( HelpHandler*=0, Topic=NO_HELP_TOPIC);
virtual bool HasHelp ();
virtual void SetHandler (HelpHandler*, Topic);
virtual void Handlehelp ();
private:
HelpHandler* _successor;
Topic _topic;
}
HelpHandler:: HelpHandler (HelpHandler* h, Topic t): _successor(h), _topic(t) {}
bool HelpHandler::HasHelp () {
return (_topic != NO_HELP_TOPIC);
}
void HelpHandler:: HandleHelp() {
if ( _successor != 0 ) {
_successor->HandleHelp();
}
5
COSC 3351 – Software Design
Edgar Gabriel
class Widget: Public HelpHandler {
protected:
Widget( Wdiget* parent, Topic t=NO_HELP_TOPIC);
private:
Widget* _parent;
}
Widget:: Widget (Widget *w, Topic t): HelpHandler(w,t){
_parent = w;
}
class Button : public Widget {
public:
Button (Widget *d, Topic t=NO_HELP_TOPIC);
virtual void HandleHelp();
}
Button::Button (Widget *d, Topic t) : Widget (d,t) {}
void Button::HandleHelp() {
if ( HasHelp() ) {
//offer help on the Button
} else {
HelpHandler::HandleHelp();
}
}
COSC 3351 – Software Design
Edgar Gabriel
// Application is not a widget
class Application: Public HelpHandler {
public:
Application(Topic t): HelpHandler(0,t);
virtual void HandleHelp();
}
void Application::HandleHelp() {
// print list of topics, do not forward
}
// Code to set up the chain of HelpHandlers
Application *app = new Application (APPLICATION_TOPIC);
Button *button1 = new Button ( app, PRINT_TOPIC);
Button *button2 = new Button ( button1, PAPER_ORIENTATION);
…
a call to button2->HandleHelp will initiate the chain
6
COSC 3351 – Software Design
Edgar Gabriel
Command
• Intent: encapsulate a request as an object, thereby
letting you
– parameterize clients with different requests
– queue or log requests
– support undo-operations
• Also known as: Transaction pattern
COSC 3351 – Software Design
Edgar Gabriel
Structure
Client
<<interface>>
Command
Execute()
ConcreteCommand
Execute()
Receiver
Action()
Invoker
state
7
COSC 3351 – Software Design
Edgar Gabriel
Participants
• Command: declares an interface for executing an
operation
• ConcreteCommand:
– defines a binding between the Receiver object and an action
– implements Execute by invoking the corresponding operation on Receiver
• Client: create a ConcreteCommand object and its
receiver
• Invoker: asks the command to carry out the request
• Receiver: knows how to perform the operation
associated with carrying out a request
COSC 3351 – Software Design
Edgar Gabriel
Example: A graphical User Interface
• Each choice in a Menu is an instance of a MenuItem
class
• An Application class
– creates the MenuItems along with the rest of the interface
– keeps track of the Document objects that are open
– configures each MenuItem with a concrete Command subclass
– When the user selects a MenuItem, the MenuItem calls Execute of the on its command subclass, which carries out the operation
8
COSC 3351 – Software Design
Edgar Gabriel
Outline
Document
Open()
Close()
Cut()
Copy()
Paste()
Application
Add()
Menu
Add(MenuItem)
MenuItem
Clicked()
command->Execute()
<<interface>>
Command
Execute()
COSC 3351 – Software Design
Edgar Gabriel
<<interface>>
Command
Execute()
Document
Open()
Close()
Cut()
Copy()
Paste()
PasteCommand
Execute()
OpenCommand
Execute()
AskUser()
document->Paste() name = AskUser();
doc = new Document(name);
application->Add(doc);
doc->Open();
9
COSC 3351 – Software Design
Edgar Gabriel
Supporting Undo
• The Command pattern can support Undo and redo
operations
– have to provide a way to reverse execution in the Command interface
– might require storage of additional state, such as
• the Receiver object
• arguments to the operation performed on the receiver
• any original values in the receiver
– History list, if more than one operation should be undoable
• Undoable command might have to copy entire objects
before being placed on the history list
– i.e. for undoing delete operation
COSC 3351 – Software Design
Edgar Gabriel
Mediator
• Intent: define an object that encapsulates how a set of
objects interact
• Applicability: use the Mediator pattern when
– a set of objects communicate in a well-defined but complex way. The resulting interdependencies are unstructured and difficult to understand
– 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
10
COSC 3351 – Software Design
Edgar Gabriel
Structure
<<interface>>
Colleague
<<interface>>
Mediator
ConcreteMediator ConcreteCollegue1 ConcreteCollegue2
COSC 3351 – Software Design
Edgar Gabriel
Participants
• Mediator: defines an interface fo communicating
between Colleague objects
• ConcreteMediator: implements cooperative behavior by
Coordinating Colleague objects
• ConcreteColleagues:
– each Colleague knows it Mediator object
– each colleague communicates with its mediator whenever it would have otherwise communicated with another colleague
11
COSC 3351 – Software Design
Edgar Gabriel
Consequences
• The Mediator pattern:
– limits subclassing by localizing behavior that otherwise would be distributed among multiple objects
– decouples colleagues
– simplifies the object protocol, since it replaces many-to-many interactions with one-to-many interactions
– abstracts away how objects cooperate
– centralizes control – the mediator pattern trades complexity of interaction for complexity in the mediator
• the class can become a lot more complex than any individual colleague!
COSC 3351 – Software Design
Edgar Gabriel
Observer
• Intent: define a one-to-many dependency between
objects so that when one objects changes state, all its
dependents are notified and updates automatically
• Applicability: Use the observer pattern
– when an abstraction has two aspects, one dependent on another
– then changes to one object require changing other objects, and you don’t know how many objects need to be changed
– when an object should be able to notify other objects without making assumptions about who these objects are.
12
COSC 3351 – Software Design
Edgar Gabriel
Structure
<<interface>>
Subject
Attach(Observer)
Detach(Observer)
Notify()
ConcreteSubject
GetState()
SetState()
subjectstate
<<interface>>
Observer
Update()
ConcreteObserver
Update()
observerstate
for all o in observer {
o->Update()
}
return subjectstate;
observerstate = subject->GetState();
COSC 3351 – Software Design
Edgar Gabriel
Participants• Subject:
– knows its observers. Any number of Observer objects may
observe a subject
– provides an interface for attaching and detaching Observer
objects
• Observer: defines an updating interface for objects that should be
notified of changes in a subject
• ConcreteSubject:
– stores state of interest to ConcreteObserver objects
– sends a notification to its observers when its state changes
• ConcreteObserver:
– maintains a reference to a ConcreteSubject object
– stores state that should stay consistent with subject
– implements the Observers updating interface to keep its state consistent with the subject
13
COSC 3351 – Software Design
Edgar Gabriel
Who triggers the update?
• Option 1: make state-setting operations on Subject call
Notify() automatically
– clients don’t need to remember to call Notify
– several consecutive operations will cause several consecutive updates, although they could be bundled.
• Option 2: make the client call the update operation
– solves the multi-update problem
– more error prone
COSC 3351 – Software Design
Edgar Gabriel
Push vs. Pull model
• Push Model:
– subject sends observers detailed information about the change
– subject does not distinguish whether the observers is interested in all type of state changes
• Pull Model:
– subject only minimal notification
– observer asks for details for events of interest
• 3rd Alternative: introduce the notion of interest in the
Attach operation of a subject, e.g.
void Subject::Attach ( Observer*, Aspect& interest);
14
COSC 3351 – Software Design
Edgar Gabriel
ChangeManager
• Additional entity introduced when dependency
relations between subjects and observers are complex
• Responsibilities:
– map a subject to its observers and provide an interface to maintain this mapping
– define particular update strategies
– update all dependent observers at the request of a subject
• ChangeManager often acts as mediator between
subjects and observers, since it encapsulates complex
update semantics
• ChangeManager is usually unique, i.e. it may use the
Singleton pattern
COSC 3351 – Software Design
Edgar Gabriel
Example
• Model-View-Controller:
– Model is the subject
– View is the Observer