COSC 340: Software Engineering

Design Patterns

Michael Jantz

Recommended text: : Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides

COSC 340: Software Engineering 1 Why Design Patterns?

• Designing object-oriented software is hard ‒ Designing reusable object-oriented software is even harder • Good designers do not solve every problem from first principles ‒ When a good solution is found, reuse it over and over again • Patterns make it easier to reuse successful designs and architectures ‒ Pattern vocabulary makes systems more accessible to new developers ‒ Help you choose reusable designs ‒ Improve the documentation and maintainability of existing systems ‒ Help you get the design 'right' faster

COSC 340: Software Engineering 2 Elements of Design Patterns

• Pattern name ‒ A one or two word handle for describing the pattern • Problem ‒ When to apply the pattern (the problem and its context) • Solution ‒ Elements of the design, their relationships, responsibilities and collaborations • Consequences ‒ Results and trade-offs of applying the pattern

COSC 340: Software Engineering 3 What is a Design Pattern?

• Depends on your point of view • Useful to concentrate on a certain level of abstraction ‒ Do not consider objects that can be encoded and reused as is (e.g. linked lists and hash tables) ‒ Do not consider complex, domain-specific designs for an entire system • GoF Definition: ‒ Design patterns are "descriptions of communicating objects and classes that are customized to solve a general design problem in a particular context"

COSC 340: Software Engineering 4 Classifying Design Patterns

• Purpose (what does the pattern do?) ‒ Creational (object creation) ‒ Structural (composition of classes or objects) ‒ Behavioral (characterize object interaction) • Scope (where does it apply – classes or objects?) ‒ Class patterns • Deal with relationships b/w classes and their subclasses • Static – fixed at compile time ‒ Object patterns • Deal with object relationships • More dynamic – can be changed at runtime

COSC 340: Software Engineering 5 Organizing the Catalog

Purpose Creational Structural Behavioral Class Factory Method Adapter Interpreter Template Method Abstract Factory Adapter Chain of Responsibility Builder Bridge Command Prototype Composite Iterator Scope Singleton Decorator Mediator Object Façade Memento Proxy Flyweight Observer State Strategy Visitor 6 OMT Notation

• Three diagrammatic notations ‒ Class diagram • depicts classes, their structure, and the static relationships between them ‒ Object diagram • depicts a particular object structure at run-time ‒ Interaction diagram • shows the flow of requests between objects

COSC 340: Software Engineering 7 Class Diagrams

8 Class Diagrams

9 Object Diagrams

COSC 340: Software Engineering 10 Interaction Diagram

COSC 340: Software Engineering 11 Creational Patterns

• Abstract away the instantiation process • Two recurring themes in creational patterns ‒ Encapsulate knowledge about which concrete classes the system uses ‒ Hide how instances of these classes are created and put together

COSC 340: Software Engineering 12 Driving Example: Maze for a Computer Game

• Focus only on how the maze is created ‒ Ignore players, operations for displaying and wandering around the maze, etc. • Maze definition ‒ Maze is a set of rooms ‒ Each room knows its neighbors ‒ Possible neighbors are another room, a wall, or a door to another room • Maze classes ‒ Room, Door, and Wall

COSC 340: Software Engineering 13 Maze Class Diagram

COSC 340: Software Engineering 14 MazeGame::CreateMaze

COSC 340: Software Engineering 15 MazeGame::CreateMaze

• Problem: CreateMaze is inflexible • Classes that get instantiated are hard-coded into this design

• Creational patterns make this design more flexible • Allows you to remove explicit references to concrete classes

COSC 340: Software Engineering 16

• Intent ‒ Define an interface for creating an object, but let subclasses decide which class to instantiate • Motivation ‒ Frameworks with abstract classes often need to create objects when it is not known what kind of object to create ‒ The framework must instantiate classes, but it only knows about abstract classes, which it cannot instantiate • Solution ‒ Encapsulate the knowledge of the subclass to create and move this knowledge out of the framework

COSC 340: Software Engineering 17 Factory Method Pattern: Structure

COSC 340: Software Engineering 18 Factory Method Pattern: Implementation Two Major Variations

• Creator is an abstract class ‒ Requires subclasses to define a factory method implementation • Creator is a concrete class with a default factory method implementation ‒ Factory method can be overridden for flexibility ‒ Follows the rule "create objects in a separate operation so that subclasses can override the way they're created."

COSC 340: Software Engineering 19 Factory Method Pattern: MazeGame Example MazeGame Class and Maze Creation Code

20 Factory Method Pattern: MazeGame Example Potential Subclasses for MazeGame

COSC 340: Software Engineering 21 Factory Method Pattern: Applicability

• Use the Factory Method pattern when ‒ A class can't anticipate the class of objects it must create ‒ A class wants its subclasses to specify the objects it creates ‒ Classes delegate responsibility to one of several helper subclasses

COSC 340: Software Engineering 22 Factory Method Pattern: Consequences Advantages and Disadvantages

• Advantages ‒ Eliminate the need to bind concrete classes into your abstract code ‒ Provides hooks for subclasses ‒ Allows you to connect parallel class hierarchies (see next slide) • Disadvantage ‒ Might have to subclass the Creator just to create a particular type of object

COSC 340: Software Engineering 23 Factory Method Pattern: Consequences Connecting Parallel Class Hierarchies

• Consider a graphical program that manipulates figures interactively • Use a Manipulator class to implement interactions and keep of track of state • Factory Method enables the client code to create the Manipulator objects

COSC 340: Software Engineering 24

• Intent ‒ Provide an interface for creating families of related objects without specifying their concrete classes • Motivation ‒ It is often useful to define a portable interface for creating objects that can be reused in different environments or situations ‒ Example: creating widgets with different look-and-feel standards • Solution ‒ Use an abstract class to define an interface for creating each kind of object as well as abstract classes for each kind of object ‒ Define concrete subclasses to implement functionality specific to a particular situation or environment

COSC 340: Software Engineering 25 Abstract Factory Pattern: Motivation Look-and-Feel Example

• Desktop environment defines multiple look-and-feel standards ‒ Different look-and-feels change the way user-interface widgets (scroll bars, windows, buttons, etc.) are displayed ‒ Application code should not hard code widgets for a single look-and-feel • Abstract Factory design ‒ Application code interacts with abstract classes ‒ Use concrete subclasses to define the different look-and-feel standards

COSC 340: Software Engineering 26 Abstract Factory Pattern: Motivation Look-and-Feel Example

COSC 340: Software Engineering 27 Abstract Factory Pattern: Structure

COSC 340: Software Engineering 28 Abstract Factory Pattern: Participants

• AbstractFactory (WidgetFactory) ‒ Declares an interface for operations that create abstract product objects • ConcreteFactory (MotifWidgetFactory, PMWidgetFactory) ‒ Implements the operations to create concrete product objects • AbstractProduct (Window, ScrollBar) ‒ Declares an interface for a type of product object • ConcreteProduct (MotifWindow, MotifScrollBar) ‒ Defines a product object to be created by the corresponding concrete factory ‒ Implements the AbstractProduct interface • Client ‒ Uses only interfaces declared by AbstractFactory and AbstractProduct classes

COSC 340: Software Engineering 29 Abstract Factory Pattern: Maze Example MazeFactory Implementation

• Maze building programs take an instance of MazeFactory as an argument

COSC 340: Software Engineering 30 Abstract Factory Pattern: Maze Example Parameterizing CreateMaze

COSC 340: Software Engineering 31 Abstract Factory Pattern: Maze Example ConcreteFactory Implementations

• Subclass of MazeFactory • Overrides member functions and returns different instances of rooms and doors

COSC 340: Software Engineering 32 Abstract Factory Pattern: Maze Example ConcreteFactory Implementations

• BombedMazeFactory ensures: • Walls are of class BombedWall • Rooms are of class RoomWithABomb

• To build a simple maze with bombs, call CreateMaze with BombedMazeFactory

COSC 340: Software Engineering 33 Abstract Factory Pattern: Maze Example MazeFactory Implementation

• MazeFactory is a collection of factory methods • MazeFactory acts as both the AbstractFactory and a ConcreteFactory

COSC 340: Software Engineering 34 Prototype Pattern

• Intent ‒ Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype • Motivation ‒ Useful for when a system needs to be independent of how its objects are created, composed, and represented ‒ Enables you to avoid building a class hierarchy of factories that parallels the class hierarchy of products ‒ Example: graphical application for editing musical scores • Solution ‒ Parameterize object creation methods with prototype instance ‒ Create the appropriate objects by copying the prototype

COSC 340: Software Engineering 35 Prototype Pattern: Example Graphical Application for Editing Musical Scores

• Approach: use a general framework for creating graphical apps • The framework includes a palette of tools for ‒ Adding new music objects (notes, rests, staves) ‒ Selecting, moving, manipulating music objects • Framework design ‒ Abstract graphic class for graphical components ‒ Abstract tool class for defining tools in the palette ‒ GraphicTool class • Creates graphical objects and adds them to the document • Problem: GraphicTool should be part of the (general) graphical framework, but the graphical objects (notes, staves) are specific to the application

COSC 340: Software Engineering 36 Prototype Pattern: Example Graphical Application for Editing Musical Scores

• Solution: GraphicTool creates new graphics by cloning a prototype instance of a Graphic subclass • GraphicTool is parameterized by the prototype it should clone and add to the document 37 Prototype Pattern: Structure

COSC 340: Software Engineering 38 Prototype Pattern: Participants

• Prototype (Graphic) ‒ Declares an interface for cloning itself • ConcretePrototype (Staff, WholeNote, HalfNote) ‒ Implements an operation for cloning itself • Client (GraphicTool) ‒ Creates a new object by asking a prototype to clone itself

COSC 340: Software Engineering 39 Prototype Pattern: Maze Example

COSC 340: Software Engineering 40 Prototype Pattern: Maze Example

41 Prototype Pattern: Maze Example

• Initialize with basic maze components to create a prototypical or default maze

COSC 340: Software Engineering 42 Prototype Pattern: Maze Example

• Initialize with bomb maze components to create a maze with bombs

COSC 340: Software Engineering 43 Prototype Pattern: Maze Example

• Original definition for Door

• Prototype pattern definition for Door 44 Prototype Pattern: Maze Example

• Note: BombedWall::Clone returns a Wall*, but the implementation always returns a BombedWall* • This design ensures code that clone the prototype do not have to know about concrete subclasses

COSC 340: Software Engineering 45 Structural Patterns

• Compose classes and objects to form larger structures • Two types ‒ Structural class patterns use inheritance to compose interfaces or implementations ‒ Structural object patterns compose objects to realize new functionality • Structural patterns we will cover ‒ Composite ‒ Decorator ‒ Adapter

COSC 340: Software Engineering 46

• Compose objects into tree structures that let you treat individual objects and compositions of objects uniformly • Motivation ‒ Having to distinguish between primitive objects and compositions of primitive objects can make the application more complex ‒ Example: grouping components of a graphical application • Solution ‒ Use recursive composition of objects ‒ Use an abstract class to represent both primitive objects and their containers

COSC 340: Software Engineering 47 Composite Pattern: Motivation Grouping Components in a Graphical Application

• Graphics applications (e.g. drawing editors) often build diagrams out of simple components ‒ Users group components to form larger components • Simple approach: classes for primitive objects (Line, Text) and classes for container objects ‒ Problem: code must treat these objects differently – even if the user treats them identically ‒ Desire a common interface for using and representing both primitive and container objects

COSC 340: Software Engineering 48 Composite Pattern: Motivation Grouping Components in a Graphical Application

COSC 340: Software Engineering 49 Composite Pattern: Structure

COSC 340: Software Engineering 50 Composite Pattern: Participants

• Component (Graphic) ‒ Declares the interface for objects in the composition ‒ Implements default behavior for the interface common to all classes, as appropriate ‒ Declares an interface for accessing and managing its child components ‒ (optional) defines an interface for accessing a component's parent in the recursive structure, and implements it if that's appropriate • Leaf (Rectangle, Line, Text, etc.) ‒ Represents leaf objects in the composition (a leaf has no children) ‒ Defines behavior for primitive objects in the composition • Composite (Picture) ‒ Defines behavior for components having children ‒ Stores child components ‒ Implements child-related operations in the Component • Client ‒ Manipulates objects in the composition through the Component interface.

COSC 340: Software Engineering 51 Composite Pattern: Example Electronic Equipment

• The Equipment class defines an interface for a hierarchy of electronic equipment

COSC 340: Software Engineering 52 Composite Pattern: Example Electronic Equipment

• FloppyDisk is a Leaf class • It defines the interface for one of the individual components in the hierarchy

COSC 340: Software Engineering 53 Composite Pattern: Example Electronic Equipment

• CompositeEquipment is a base class for equipment that contains other equipment

COSC 340: Software Engineering 54 Composite Pattern: Example Electronic Equipment

• Operations for CompositeEquipment are defined in terms of their children

COSC 340: Software Engineering 55 Composite Pattern: Example Electronic Equipment

• Client code treats Equipment and CompositeEquipment objects in a uniform way

COSC 340: Software Engineering 56 Composite Pattern: Consequences Benefits and Drawbacks

• Results in class hierarchies consisting of primitive objects and composite objects • Benefits ‒ Makes the client simpler ‒ Makes it easier to add new types of components • Drawbacks ‒ Can make your design overly general

COSC 340: Software Engineering 57

• Convert (or "adapt") the interface of a class into another interface expected by the client code • Also known as "wrapper" • Motivation ‒ A toolkit might not be usable only because its interface does not match the domain-specific interface expected by the application ‒ Example: drawing editor program with text boxes • Solution ‒ Use multiple inheritance to adapt one interface to another ‒ Use object composition to implement one interface in terms of another

COSC 340: Software Engineering 58 Adapter Pattern: Motivation DrawingEditor Program

• Program allows users to draw and arrange graphical elements (lines, polygons, text) into pictures and diagrams ‒ Shape class defines graphical objects (has an editable shape and can draw itself) ‒ Each kind of graphical object is a subclass of shape (LineShape, PolygonShape, etc) • TextShape is more difficult to implement ‒ TextView class available from another toolkit, but does not fit the Shape interface ‒ How to use TextView even though our drawing class must conform to a different and incompatible interface? ‒ Solution: create an adapter class that adapts TextView's interface for use with the Drawing Editor program

COSC 340: Software Engineering 59 Adapter Pattern: Motivation DrawingEditor Program

COSC 340: Software Engineering 60 Adapter Pattern: Structure Using Object Composition

COSC 340: Software Engineering 61 Adapter Pattern: Structure Using Multiple Inheritance

COSC 340: Software Engineering 62 Adapter Pattern: Participants

• Target (Shape) ‒ Defines the domain-specific interface that Client uses • Client (DrawingEditor) ‒ Collaborates with objects conforming to the Target interface • Adaptee (TextView) ‒ Defines an existing interface that needs adapting • Adapter (TextShape) ‒ Adapts the interface of Adaptee to the Target interface

COSC 340: Software Engineering 63 Adapter Pattern: Sample Code

COSC 340: Software Engineering 64 Adapter Pattern: Sample Code Using Multiple Inheritance

COSC 340: Software Engineering 65 Adapter Pattern: Sample Code Using Multiple Inheritance

66 Adapter Pattern: Sample Code Using Object Composition

COSC 340: Software Engineering 67 Adapter Pattern: Sample Code Using Object Composition

COSC 340: Software Engineering 68

• Attach additional responsibilities to an object dynamically • Also known as "wrapper" • Motivation ‒ Often want to add responsibilities to individual objects, not an entire class ‒ Class inheritance can be inflexible • Solution ‒ Enclose the target object in another object that adds the functionality ‒ The enclosing object is called a decorator ‒ The decorator forwards requests to the target and may perform additional actions before or after forwarding

COSC 340: Software Engineering 69 Decorator Pattern: Example aTextView with aScrollDecorator and aBorderDecorator

COSC 340: Software Engineering 70 Decorator Pattern: Example aTextView with aScrollDecorator and aBorderDecorator

COSC 340: Software Engineering 71 Decorator Pattern: Structure

COSC 340: Software Engineering 72 Decorator Pattern: Participants

• Component (VisualComponent) ‒ Defines the interface for objects that can have responsibilities added to them dynamically • ConcreteComponent (TextView) ‒ 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's interface • ConcreteDecorator (BorderDecorator, ScrollDecorator) ‒ Adds responsibilities to the component

COSC 340: Software Engineering 73 Decorator Pattern: Sample Code

• VisualComponent is the Component abstract base class

COSC 340: Software Engineering 74 Decorator Pattern: Sample Code

• Decorator subclass is used as a base class for creating new decorations • For operations declared in the VisualComponent interface, Decorator passes the request to the _component object

COSC 340: Software Engineering 75 Decorator Pattern: Sample Code

• Subclasses of Decorator define specific decorations

COSC 340: Software Engineering 76 Decorator Pattern: Sample Code

• Placing a TextView into the window with no decoration

COSC 340: Software Engineering 77 Decorator Pattern: Sample Code

• Adding a TextView with border and scrolling capabilities

COSC 340: Software Engineering 78 Decorator Pattern: Consequences Benefits and Liabilities

• Benefits ‒ More flexibility than static inheritance • Responsiblities added / removed at run-time • Inheritance requires a new class for each additional responsiblity ‒ Avoids feature-laden classes high up in the hierarchy • Liabilities ‒ A decorator and its component are not identical • Complicates testing for identity ‒ Lots of little objects

COSC 340: Software Engineering 79

• Intent ‒ Ensure a class only has one instance, and provide a global point of access to it • Motivation ‒ Often important for classes to have exactly one instance (e.g. we only want one file system or window manager) ‒ Global variable does not prevent you from instantiating multiple objects • Solution ‒ Class itself is responsible for keeping track of the sole instance ‒ The class ensures no other instances can be created, and provides access to the sole instance

COSC 340: Software Engineering 80 Singleton Pattern Implementation: Ensuring a Unique Instance

COSC 340: Software Engineering 81 Singleton Pattern Implementation: Ensuring a Unique Instance

• Access the singleton through the Instance function

• _instance variable initialized on first access

• Why not just define a global or static instance variable (initialize automatically)? • Cannot guarantee only one instance of the Singleton type • Runtime initialization allows you to define when the object is initialized

COSC 340: Software Engineering 82 Singleton Pattern Example: MazeFactory

COSC 340: Software Engineering 83 Singleton Pattern Example: MazeFactory

COSC 340: Software Engineering 84 Singleton Pattern: Uses and Benefits

• Use Singleton when ‒ There must be exactly one instance of a class, and it must be accessible from a well-known access point ‒ The sole instance should be extensible by sub-classing, and you want to be able to use an extended instance without modifying other code • Benefits ‒ Controlled access to a single instance ‒ Reduced name space (no global variables in the name space) ‒ Singleton class can be sub-classed – and you can configure the application with an instance of the class you need at run-time ‒ Can flexibly change the number of allowable instances

COSC 340: Software Engineering 85 Behavioral Patterns

• Concerned with algorithms and the assignment of responsibilities between objects • Two types ‒ Behavioral class patterns ‒ Behavioral object patterns • Behavioral patterns we will look at ‒ Template Method ‒ Observer ‒ Iterator

COSC 340: Software Engineering 86

• Define the skeleton of an algorithm in an operation, deferring some steps to subclasses • Motivation ‒ Often useful to allow subclasses to redefine parts of an algorithm without changing the algorithm's structure • Solution ‒ Define an algorithm in terms of abstract operations that subclasses override to provide concrete behavior • Example: app framework with Application and Document classes

COSC 340: Software Engineering 87 Template Method Pattern: Example Application Framework with Application and Document classes

COSC 340: Software Engineering 88 Template Method Pattern: Example Application Framework with Application and Document classes

• TM fixes the ordering of the steps, but allows subclasses to vary what happens at each step

COSC 340: Software Engineering 89 Template Method Pattern: Structure

COSC 340: Software Engineering 90 Template Method Pattern: Participants

• AbstractClass (Application) ‒ Defines abstract primitive operations that concrete subclasses define to implement steps of an algorithm ‒ Implements a template method defining the skeleton of an algorithm • ConcreteClass (MyApplication) ‒ Implements the primitive operations to carry out subclass-specific steps of the algorithm

COSC 340: Software Engineering 91

• Define a dependencies between objects so that when one object changes state, all its dependents are updated automatically • Motivation ‒ Often need to maintain consistency between related objects ‒ But want to avoid making the classes tightly coupled • Solution ‒ Define a one-to-many relationship between subject and observers ‒ Observers are notified whenever the subject changes state ‒ In response, each observer queries the subject to synchronize its state with the subject's state

COSC 340: Software Engineering 92 Observer Pattern: Example Model and View Components

• View components (spreadsheet, bar chart, etc.) are dependent on the Model component and should be notified when the Model changes • Observer pattern • Establishes a subject / observer relationship • Subject sends a message to the observers when the state has changed • Also known as publish-subscribe • Subject publishes notifications • Any number of observers can subscribe

COSC 340: Software Engineering 93 Observer Pattern: Structure

COSC 340: Software Engineering 94 Observer Pattern: 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 the subject's ‒ Implements the Observer updating interface to keep its state consistent with the subject's

COSC 340: Software Engineering 95 Observer Pattern: Collaborations

COSC 340: Software Engineering 96 Observer Pattern: Sample Code

• Abstract class for the Observer interface • Supports multiple subjects for each observer

COSC 340: Software Engineering 97 Observer Pattern: Sample Code

• Abstract class for the Subject interface

98 Observer Pattern: Sample Code

• ClockTimer is a concrete subject for maintaining the time of day

• Tick is called by an internal timer at regular intervals

COSC 340: Software Engineering 99 Observer Pattern: Sample Code

• DigitalClock class for displaying the time

COSC 340: Software Engineering 100 Observer Pattern: Sample Code

• Constructor and destructor attach and detach the DigitalClock from its subject

• On update, draw the digital clock with the updated hour and minute

101 Observer Pattern: Sample Code

• Code for creating an AnalogClock and DigitalClock with the same subject • Whenever the timer ticks, the clocks update and redisplay themselves

COSC 340: Software Engineering 102 Observer Pattern: Consequences Benefits and Liabilities

• Allows you to vary subjects and observers independently • Loose coupling between subject and observer • Support for broadcast communication • Unexpected updates ‒ Observers and other client code might not consider the ultimate cost of changing the subject

COSC 340: Software Engineering 103 Observer Pattern: Implementation Issues Encapsulating complex update semantics

• If dependency between subjects and observers is complex, use a separate object to maintain their relationships • The ChangeManager object aims to minimize the work of updating the observer objects • Three responsibilities for ChangeManager ‒ Map a subject to its observers ‒ Define a particular update strategy ‒ Update all dependent observers at the request of a subject

COSC 340: Software Engineering 104 Observer Pattern: Implementation Issues Encapsulating complex update semantics

• DAGChangeManager handles DAGs of dependencies between subjects and observers • Avoids redundant updates when observers have multiple subjects 105

• Provide a way to access elements of an aggregate object sequentially without exposing its underlying representation • Motivation ‒ Aggregate objects should have a way to access their elements without exposing their internal structures ‒ Might also want to traverse the aggregate object in different ways ‒ Or have more than one traversal pending at a time • Solution ‒ Responsibility for access and traversal is removed from the aggregate object and put into an iterator object ‒ Iterator class defines an interface for accessing the object's elements ‒ Each iterator object keeps track of the current element

COSC 340: Software Engineering 106 Iterator Pattern: Example List class with a ListIterator

• Creating a ListIterator instance requires a List to traverse • ListIterator allows you to access List items sequentially • ListIterator methods ‒ CurrentItem: current element in the list ‒ First: initializes current element to the first element ‒ Next: advances the current element to the next element ‒ IsDone: tests whether we've advanced past the last element

COSC 340: Software Engineering 107 Iterator Pattern: Example List class with a ListIterator

• Simple approach requires the client code to know that the object it wants to traverse is a List • Instead, we can define an abstract Iterator class to support polymorphic iteration.

COSC 340: Software Engineering 108 Iterator Pattern: Example List class with a ListIterator

• Want to be able to write client code for both List and SkipList objects • Define an abstract List class and abstract Iterator class

109 Iterator Pattern: Structure

COSC 340: Software Engineering 110 Iterator Pattern: Participants

• Iterator ‒ Defines an interface for accessing and traversing elements • ConcreteIterator ‒ Implements the Iterator interface ‒ Keeps track of the current position in the traversal of the aggregate • Aggregate ‒ Defines an interface for creating an Iterator object • ConcreteAggregate • Implements the Iterator creation interface to return an instance of the proper ConcreteIterator.

COSC 340: Software Engineering 111 Iterator Pattern: Sample Code Interface Definitions

• List interface • Iterator interface

COSC 340: Software Engineering 112 Iterator Pattern: Sample Code Concrete ListIterator Definition

COSC 340: Software Engineering 113 Iterator Pattern: Sample Code Concrete ListIterator Definition

COSC 340: Software Engineering 114 Iterator Pattern: Sample Code Using the Iterators

COSC 340: Software Engineering 115 Iterator Pattern: Consequences

• Iterators ‒ Support variations in the traversal of aggregate objects ‒ Simplify the interface of the Aggregate class ‒ Allow more than one pending traversal on an aggregate object

COSC 340: Software Engineering 116 Backup

COSC 340: Software Engineering 117 Implementation: Subclassing the Singleton Class

118 Registering the Singleton

• Register singletons in the constructor of the subclass

• Where do you call the constructor? • Define a static instance in the file that contains the subclass implementation

COSC 340: Software Engineering 119 Factory Method Pattern: Implementation Parameterized Factory Methods

• Pass a parameter to the factory method to specify the kind of object to create • Use a class identifier to specify the type of object to create

COSC 340: Software Engineering 120 Factory Method Pattern: Implementation Parameterized Factory Methods

• Can also override the parameterized factory method to selectively extend or change the objects produced

COSC 340: Software Engineering 121 Factory Method Pattern: Implementation Using Templates to Avoid Subclassing

• Problem: Might need to subclass Creator just to create objects of the appropriate type • Solution: Use templates!

COSC 340: Software Engineering 122 Abstract Factory Pattern: Applicability

• Use the abstract factory pattern when ‒ A system should be independent of how its products are created, composed, and represented ‒ A system should be configured with one of multiple families of products ‒ A family of related product objects is designed to be used together, and you need to enforce this constraint ‒ You want to provide a class library of products, and you want to reveal just their interfaces, not their implementations

COSC 340: Software Engineering 123 Abstract Factory Pattern: Consequences

• Advantages ‒ It isolates concrete classes ‒ Exchanging product families is easy ‒ Promotes consistency among products • Disadvantage ‒ Supporting new kinds of products is difficult

COSC 340: Software Engineering 124 Abstract Factory Pattern: Implementation

• Factories as singletons ‒ Application typically only needs one instance of ConcreteFactory • Creating the products ‒ AbstractFactory only declares an interface for creating products ‒ ConcreteProduct classes actually create the objects ‒ Use factory method or prototype pattern to create the objects • Defining extensible interfaces ‒ Adding new kinds of products requires changing the AbstractFactory and everything that depends on it ‒ Possible solution: parameterize operations that create objects with something that identifies the type of object to create

COSC 340: Software Engineering 125 Prototype Pattern: Implementation Issues

• Using a prototype manager ‒ Keep a registry of available prototypes ‒ Clients do not have to manage creating / destroying prototype instances • Implementing the clone operation ‒ Tricky for objects that contain circular references ‒ Need to determine if clone should do a shallow or deep copy • Initializing clones ‒ Some clones may need to initialize additional state ‒ Values needed to initialize prototype clones vary (cannot use clone) ‒ Prototype classes often define methods for setting state that client code can use immediately after cloning (e.g. initialize)

COSC 340: Software Engineering 126 Prototype Pattern: Applicability

• Use the prototype pattern ‒ When the system should be independent of how its products are created, composed, and represented ‒ When the classes to instantiate are specified at run-time, (for example, by dynamic loading) ‒ To avoid building a class hierarchy of factories that parallels the class hierarchy of products ‒ When instances of a class can have one of only a few different combinations of state

COSC 340: Software Engineering 127 Prototype Pattern: Consequences

• Similar benefits as Abstract Factory ‒ Hides concrete classes from client code ‒ Clients can work with application-specific classes without modification • Additional Benefits ‒ Adding and removing products at runtime ‒ Specifying new kinds of objects by varying the prototype ‒ Reduced subclassing ‒ Configuring an application with classes dynamically • Drawback ‒ Implementing prototype subclasses is more complex (e.g. clone operation)

COSC 340: Software Engineering 128 Composite Pattern: Implementation Issues

• Explicit parent references ‒ Simplifies traversal / management operations • Sharing components ‒ Have children store pointers to multiple parents ‒ Can help reduce storage requirements • Where to declare management operations? ‒ In the Component class (maximizes transparency, but costs you safety) ‒ In the Composite class (improves safety, but leaves and composite have different interfaces) • What is the best data structure for storing components? ‒ Choice will impact efficiency of operations on the composite structure

COSC 340: Software Engineering 129 Decorator Pattern: Implementation

• Decorator interface must conform to the interface of the component it decorates • You can often omit the abstract Decorator class • Component classes should be lightweight • Changing the skin of an object vs. changing its guts ‒ Decorator is a skin over an object that changes its behavior ‒ Other patterns (e.g. strategy) can be applied to change the object's guts • Useful when the Component class is too heavy-weight for decorator • forwards component behavior to a separate strategy object Adapter Pattern: Applicability

• Use the Adapter Pattern when ‒ You want to use an existing class, but its interface does not match the one you need ‒ You want to create a reusable class that cooperates with unrelated or unforeseen classes ‒ (object adapter only) You need to use several existing subclasses, but it's impractical to adapt their interface by subclassing every one

COSC 340: Software Engineering 131 Adapter Pattern: Implementation

• Implementing class adapters in C++ ‒ Adapter inherits publically from Target, but privately from Adaptee • Pluggable adapters ‒ The adapter is not hard-coded against a specific adaptee ‒ TreeWidget Example • TreeWidget displays tree structures graphically • To maximize reusability, there should not be a hard requirement that TreeWidget must descend from a particular Tree abstract class • Applications might want to display different kinds of tree hierarchies (e.g. directories, subclasses) and the widget should be flexible enough to do so

COSC 340: Software Engineering 132 Adapter Pattern: Tradeoffs

• Class adapter (multiple inheritance approach) ‒ Adapts Adaptee to Target by committing to a concrete Adapter class – cannot adapt a class to all its subclasses ‒ Allows Adapter to override some of Adaptee's behavior ‒ Introduces only one object (no pointer indirection) • Object adapter (object composition approach) ‒ Allows a single Adapter to work with many Adaptees ‒ Makes it harder to override Adaptee behavior

COSC 340: Software Engineering 133

• Use sharing to support large numbers of fine-grained objects efficiently • Motivation ‒ Many applications benefit from using objects throughout their design, but a naïve implementation would use too much memory ‒ Example: graphical representation of characters in a word processor • Solution ‒ Minimize memory usage by sharing as much data as possible between objects ‒ Store intrinsic state (information that is independent of context) in the flyweight object, while extrinsic state (information that varies with context) is stored outside the object

COSC 340: Software Engineering 134 Flyweight Pattern: Example Graphical Representation of Characters in a Word Processor

• Word processor application • Uses objects to represent embedded elements (tables, figures) • Objects for each character? • Allows you to treat drawing of characters, other elements uniformly • Easy to extend with new character sets without disturbing other functionality • Cost could be prohibitive

COSC 340: Software Engineering 135 Flyweight Pattern: Example Graphical Representation of Characters in a Word Processor

• Solution: share data between objects • A flyweight is a shared object that can be used in multiple contexts simultaneously • Intrinsic state: independent of the object's context • Stored in the flyweight • Extrinsic state: depends and varies with context • Passed to the flyweight by the client

COSC 340: Software Engineering 136 Flyweight Pattern: Example Graphical Representation of Characters in a Word Processor

• Use a flyweight for each letter in the alphabet • Logically, there is an object for every occurrence of a given character

COSC 340: Software Engineering 137 Flyweight Pattern: Example Graphical Representation of Characters in a Word Processor

• Physically, one shared flyweight per character • Each occurrence of a character refers to the same instance in the flyweight pool

COSC 340: Software Engineering 138 Flyweight Pattern: Example Graphical Representation of Characters in a Word Processor

• Glyph is the abstract class for graphical objects • Extrinsic state is passed as arguments to the operations that need it

COSC 340: Software Engineering 139 Flyweight Pattern: Example Graphical Representation of Characters in a Word Processor

• Character class creates flyweight objects that only store the character code • Since (# character objects) << (# characters in the document), this approach uses much fewer objects than a naïve implementation

COSC 340: Software Engineering 140 Flyweight Pattern: Structure Class Diagram

COSC 340: Software Engineering 141 Flyweight Pattern: Structure How Flyweight Objects are Shared

COSC 340: Software Engineering 142 Flyweight Pattern: Participants

• Flyweight ‒ Declares an interface through which flyweights can receive and act on extrinsic state. • ConcreteFlyweight (Character) ‒ Implements the Flyweight interface and adds storage for intrinsic state, if any • UnsharedConcreteFlyweight (Row, Column) ‒ Not all Flyweight subclasses need to be shared ‒ The Flyweight interface enables sharing, but does not enforce it • FlyweightFactory ‒ Creates and manages flyweight objects; ensures that flyweights are shared properly • Client ‒ Maintains a reference to flyweight(s) ‒ Computes or stores the extrinsic state of flyweight(s)

COSC 340: Software Engineering 143 Flyweight Pattern: Sample Code

• Flyweight base class

COSC 340: Software Engineering 144 Flyweight Pattern: Sample Code

• Character subclass stores a character code

COSC 340: Software Engineering 145 Flyweight Pattern: Sample Code

• GlyphContext acts as a repository of extrinsic state • Maintains a mapping between a glyph and its font in different contexts

COSC 340: Software Engineering 146 Flyweight Pattern: Sample Code

• _index used to keep track of current position during Glyph traversal • GetFont uses _index as a key into a BTree that stores the Glyph-to-Font mapping

COSC 340: Software Engineering 147 Flyweight Pattern: Sample Code _fonts BTree Example

• Each node in the tree is labeled with the length of the string for which it gives the font info • Leaves in the tree point to a font, while interior nodes break the string into substrings

COSC 340: Software Engineering 148 Flyweight Pattern: Sample Code _fonts BTree Example

• The client updates the BTree whenever a font changes or glyphs are added or removed from the document ‒ For example, the code below sets the font for the word "expect" to match the surrounding words ‒ Assume the GlyphContext object has reached index 102 (the start of the word "expect") in a traversal

COSC 340: Software Engineering 149 Flyweight Pattern: Sample Code _fonts BTree Example

• BTree is updated to indicate "expect" is the same font as the surrounding words

COSC 340: Software Engineering 150 Flyweight Pattern: Sample Code

• GlyphFactory creates glyphs and ensures they're shared properly • _character array contains pointers to Character glyphs indexed by character code

COSC 340: Software Engineering 151 Flyweight Pattern: Sample Code

• Initialize _character array to 0 in the GlyphFactory constructor • Use Singleton to provide clients access to a single instance of each Character object

COSC 340: Software Engineering 152 Flyweight Pattern: Consequences

• Main effects ‒ Introduce run-time costs for transferring / computing extrinsic state ‒ Costs can be offset by space savings • Storage savings are a function of multiple factors ‒ The reduction in the total number of instances that comes from sharing ‒ The amount of intrinsic state per object ‒ Whether extrinsic state is computed or stored

COSC 340: Software Engineering 153 Flyweight Pattern: Implementation

• Applicability depends on how easy it is to remove extrinsic state from the flyweight objects ‒ Ideally, extrinsic state can be computed from a separate object structure ‒ Example: word processor stores font information in a separate map structure • Since the objects are shared ‒ Clients should not instantiate them directly ‒ Use a FlyweightFactory to manage the shared objects ‒ Might employ reference counting or GC to reclaim flyweight objects

COSC 340: Software Engineering 154 Template Method Pattern: Consequences

• Lead to an inverted control structure ‒ "Don't call us, we'll call you" • Template methods need to distinguish abstract and hook operations ‒ Hook operations might be overridden ‒ Abstract operations must be overridden • Extending a parent class operation with a hook operation

• • Derived classes always have to remember ParentClass uses TM with a hook operation to to call ParentClass::Operation Ensure parent and derived operations are called together 155 Template Method Pattern: Implementation

• Use C++ access control ‒ Primitive operations in the TM can be declared as protected ‒ Primitive operations are declared as virtual (so they can be overridden), but the TM is non-virtual • Minimize primitive operations ‒ Reduces burden on client code • Use naming conventions

COSC 340: Software Engineering 156