Title: Introduction to Design Patterns
1Introduction to Design Patterns
2Design Patterns can be simple
- Highlighting a SHAPE in a GUI application
- Possible solution Each class, such as CAR, HOUSE
implements a method called highlight - Problem Inconsistent
- Solution In class SHAPE
public void highlight() translate(1,1) draw()
translate(1,1) draw() translate(-2,-2)
3Template Method
4Template Method
- Context
- An algorithm is applicable for multiple types
- The algorithm can be broken down into primitive
operations that may be different for each type - The order of the primitive operations does not
depend on the type
- Solution
- Define an abstract superclass with a method for
the algorithm and abstract methods for the
primitive operations - Algorithm calls primitive operations in right
order - Each subclass implements primitive operations but
not the algorithm
5DPs can be language dependent
- Singleton pattern A particular class must have
only one instance. This instance may be shared
across the system.
public class Singleton // Java private
Singleton() public static Singleton
getSingleton() if (instance null)
instance new Singleton() return instance
private static Singleton instance
What about threads? Cloning?
6Singleton Pattern in Eiffel
Eiffel has once functions but no static variables
1
2
7Singleton Accessor Class
class SINGLETON_ACCESSOR feature the_instance
SINGLETON is -- Create the only instance in the
system once create Result.make() end end
8Single Instance Class
class SINGLETON creation SINGLETON_ACCESSOR ma
ke feature make is do . end end
9Most design patterns are
- More involved
- A larger number of classes and objects take part
- Language independent
- The pattern concept can be implemented in any OO
language - Lets look at some examples
10Observer Pattern
- Intent
- Define one-to-many dependency
- When one subject changes state, all observers
(dependents) are notified and correspondingly
updated - Also known as
- Dependents and Publish-Subscribe
11Observer Motivation
text view
A is 30 B is 50 C is 20
Notify change
Request modification
rectangle view
bar view
target view
12Observer Architecture
OBSERVER
SUBJECT
observers set
update
attach(observer) detach(observer) notify
TARGET_VIEW
subject
update
TEXT_VIEW
BAR_VIEW
get_state set_state
subject
update
subject
RECTANGLE_VIEW
update
13Observer Participants
- Subject
- Knows its observers
- Provides interface for attaching, detaching and
notifying its observers - Observer
- Defines an updating interface for observers
14Observer Participants 2
- Concrete subject
- Stores state of interest to concrete observers
- Notifies observers when state changes
- Concrete observer
- Maintains a reference to its concrete subject
- Stores state that corresponds to the state of the
subject - Implements Observer updating interface
15Observer Scenario
- Concrete subject updates all observers, when
state is changed by a client
CLIENT
2
1
CONCRETE_SUBJECT
4
3
CONCRETE_OBSERVER
16Observer Consequences 1
- Abstract coupling between subject and observer
- Permits changing number of observers dynamically
- Supports broadcast communication
- Can have observers depend upon more than one
subject
17Observer Consequences 2
- Need additional protocol to indicate what changed
- Can have spurious updates
- Not all observers participate in all changes
- Dangling references when subject is deleted
- Notify observers when subject is deleted
- Not an issue in an environment with garbage
collection
18Composite Pattern
- Intent
- Compose objects into tree structures representing
part-whole hierarchies - Clients deal uniformly with individual objects
and hierarchies of objects
19Composite Motivation
- Applications that have recursive groupings of
primitives and groups - Drawing programs
- lines, text, figures and groups
- Containment structure
- Subsystems and files
- Operations on groups are different than
primitives but users treat them in the same way
20Composite Drawing Example
21Composite Architecture
T?
TEXT
OVAL
LINE
draw
draw
draw
22Composite Applicability
- Represent part-whole hierarchies of objects
- Clients can ignore difference between individual
objects and compositions - Clients deal with all objects in a composition in
the same way
23Composite Consequences
- Whenever client expects a primitive it can accept
a composite - Client is simplified by removing tag-case
statements to identify parts of the composition - Easy to add new components by subclassing, client
does not change - If compositions are to have restricted sets of
components have to rely on run-time checking
24Decorator Pattern
- Intent
- Attach additional responsibilities to an object
dynamically. - Provide a flexible alternative to subclassing for
extending functionality
25Decorator Motivation
- Motivation Applicability
- Want to add responsibility to individual objects
not to entire classes - Add properties like border, scrolling, etc to any
user interface component as needed - Enclose object within a decorator object for
flexibility - Nest recursively for unlimited customization
26Decorator Example
- Compose a border decorator with a scroll
decorator for text view.
a_border_decorator
component
a_scroll_decorator
component
a_text_view
27Decorator Example Diagram
VISUAL_COMPONENT
draw
DECORATOR
TEXT_VIEW
draw
component VISUAL_ COMPONENT
BORDER_DECORATOR
SCROLL_DECORATOR
draw border_width draw_border
draw scroll_position scroll_to
28Decorator Applicability
- Add responsibilities to individual objects
dynamically and transparently - Without affecting other objects
- For responsibilities that can be withdrawn
- When subclass extension is impractical
- Sometimes a large number of independent
extensions are possible - Avoid combinatorial explosion
- Class definition may be hidden or otherwise
unavailable for subclassing
29Decorator General Structure
COMPONENT
method
CONCRETE_COMPONENT
DECORATOR
component COMPONENT
method
CONCRETE_DECORATOR_B
CONCRETE_DECORATOR_ A
method another_feature
method other_feature
30Decorator Participants
- Component
- defines the interface for objects that can have
responsibilities added to them dynamically - Concrete component
- Defines an object to which additional
responsibilities can be attached - Decorator
- Maintains a reference to a component object and
defines an interface that conforms to COMPONENT - Concrete decorator
- Add responsibilities to the component
31Decorator Consequences
- Benefits
- More flexibility than static inheritance
- Can add and remove responsibilities dynamically
- Can handle combinatorial explosion of
possibilities - Avoids feature laden classes high up in the
hierarchy - Pay as you go when adding responsibilities
- Can support unforeseen features
- Decorators are independent of the classes they
decorate - Functionality is composed in simple pieces
32Decorator Consequences 2
- Liabilities
- From object identity point of view, a decorated
component is not identical - Decorator acts as a transparent enclosure
- Cannot rely on object identity when using
decorators - Lots of little objects
- Often result in systems composed of many look
alike objects - Differ in the way they are interconnected, not in
class or value of variables - Can be difficult to learn and debug
33Visitor Pattern
- Intent
- Represent an operation to be performed on all of
the components of an object structure - Define new operations on a structure without
changing the classes representing the components
34Visitor Motivation
- Representing computer equipment
EQUIPMENT
Operations spread out OO style but ... difficult
to add a new operation
describe price
COMPOSITE_EQUIPMENT
FLOPPY_DISK
....
describe price
describe price
35Visitor Architecture
- Equipment classes are independent of the
operations - Equipment accept visitors and direct them to the
appropriate operation through polymorphism
EQUIPMENT_VISITOR
EQUIPMENT
accept
PRICING_VISITOR
CHASSIS
accept
visit_chassis
One subclass of EQUIPMENT_VISITOR for each
operation
One subclass of EQUIPMENT for each concrete piece
of equipment
36Visitor Applicability
- Object structure contains many classes of objects
with differing interfaces and want to perform
operations that depend on their concrete classes - Many distinct and unrelated operations need to be
performed - Do not want to or are unable to clutter the
concrete classes with these operations - Keep the related operations together, e.g.
operations on pricing various types of EQUIPMENT
are all in the PRICING_VISITOR class - If the object structure is shared by many
applications, Visitor puts operations into only
those applications that need them
37Visitor Applicability 2
- The classes defining the object structure rarely
change, but you often want to define new
operations over the structure - Changing object structure means redefining
interface to all visitors, which is costly - If object structure changes often, Visitor is
inappropriate
38Visitor Abstract Architecture
ELEMENT
VISITOR
accept ( VISITOR ) ...
visit_elem_A ( ELEM_A ) visit_elem_B ( ELEM_B )
...
ELEM_A
CONCRETE_VISITOR_1
accept ( VISITOR ) ...
visit_elem_A ( ELEM_A ) visit_elem_B ( ELEM_B )
...
CONCRETE_VISITOR_2
39Visitor Participants
- Element
- Declares accept method that takes a visitor as
an argument - Concrete element
- Implements the accept method
- Visitor
- Declares a visit operation for each concrete
element class
40Visitor Participants 2
- Concrete visitor
- Implements every visit operation declared in
Visitor - Each visit operation implements a fragment of
the algorithm defined for the concrete visitor - Provides the context for the algorithm composed
of all of the visit fragments - State accumulates with each visit
- Implements the high level organization
- Iteration over the components
- Processing each in turn
41Visitor Scenario
- A pricing visitor visits a composite equipment
- For each equipment, the pricing visitor selects
which method from the EQUIPMENT_VISITOR interface
to execute
Scenario Visit a cabinet
1 Accept the pricing visitor 2 visit_cabinet 3
visit_children 4 Accept the pricing visitor
42Visitor Consequences
- Adding new operations is easy
- New operation implements the Visitor interface,
e.g. the methods in EQUIPMENT_VISITOR - All the fragments of the visitor algorithm are in
one file related behaviours are together - Easier to make sure that elements are working in
unison - Unrelated operations and fragments are in other
visitor classes - Contrast with having to change each of the
concrete element classes to have the operation
fragment - Each class has a fragment of each of the
operations
43Visitor Consequences 2
- Adding new concrete elements is difficult
- Need to modify the Visitor interface
- Need to modify each concrete visitor
- Can sometimes simplify as many elements have
common behaviour (default behaviour) that can be
specified at concrete visitor level 1. - Create subclasses of level 1 for more specific
behaviour for the new elements - Only program the new elements
- For many structures elements do not change
rapidly so this is not a problem
44Visitor Consequences 3
- One can visit object structures composed of
unrelated objects - The various visit_ methods do not have to take
arguments that are related - The main difference between Visitor and Iterator
- State accumulation
- Visitors contain data structures related to the
operation they implement, e.g. the
PRICING_VISITOR contains the total price - Without a visitor, such data would have to be
passed as arguments (or become global variables)