COSC 340: Software Engineering Design Patterns Michael Jantz - - PowerPoint PPT Presentation

cosc 340 software engineering design patterns
SMART_READER_LITE
LIVE PREVIEW

COSC 340: Software Engineering Design Patterns Michael Jantz - - PowerPoint PPT Presentation

COSC 340: Software Engineering Design Patterns Michael Jantz Recommended text: Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides COSC 340: Software Engineering 1 Why


slide-1
SLIDE 1

COSC 340: Software Engineering Design Patterns

Michael Jantz

COSC 340: Software Engineering 1

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

slide-2
SLIDE 2

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

slide-3
SLIDE 3

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

slide-4
SLIDE 4

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

slide-5
SLIDE 5

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

slide-6
SLIDE 6

Organizing the Catalog

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

6

slide-7
SLIDE 7

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

slide-8
SLIDE 8

Class Diagrams

8

slide-9
SLIDE 9

Class Diagrams

9

slide-10
SLIDE 10

Object Diagrams

COSC 340: Software Engineering 10

slide-11
SLIDE 11

Interaction Diagram

COSC 340: Software Engineering 11

slide-12
SLIDE 12

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

slide-13
SLIDE 13

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

slide-14
SLIDE 14

Maze Class Diagram

COSC 340: Software Engineering 14

slide-15
SLIDE 15

MazeGame::CreateMaze

COSC 340: Software Engineering 15

slide-16
SLIDE 16

MazeGame::CreateMaze

COSC 340: Software Engineering 16

  • 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

slide-17
SLIDE 17

Factory Method Pattern

  • 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

slide-18
SLIDE 18

Factory Method Pattern: Structure

COSC 340: Software Engineering 18

slide-19
SLIDE 19

Factory Method Pattern: Implementation

Two Majo jor Vari riatio ions

  • 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

  • verride the way they're created."

COSC 340: Software Engineering 19

slide-20
SLIDE 20

Factory Method Pattern: MazeGame Example

MazeGame Class and Maze Creation Code

20

slide-21
SLIDE 21

Factory Method Pattern: MazeGame Example

Potential Subclasses for MazeGame

COSC 340: Software Engineering 21

slide-22
SLIDE 22

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

slide-23
SLIDE 23

Factory Method Pattern: Consequences

Advantages and Disa isadvantages

  • 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

slide-24
SLIDE 24

Factory Method Pattern: Consequences

Connecting Parallel Class Hierarchies

COSC 340: Software Engineering 24

  • 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
slide-25
SLIDE 25

Abstract Factory Pattern

  • 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

slide-26
SLIDE 26

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

slide-27
SLIDE 27

Abstract Factory Pattern: Motivation

Look-and-Feel Example

COSC 340: Software Engineering 27

slide-28
SLIDE 28

Abstract Factory Pattern: Structure

COSC 340: Software Engineering 28

slide-29
SLIDE 29

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

slide-30
SLIDE 30

Abstract Factory Pattern: Maze Example

MazeFactory Implementation

COSC 340: Software Engineering 30

  • Maze building programs take an instance of MazeFactory as an argument
slide-31
SLIDE 31

Abstract Factory Pattern: Maze Example

Parameterizing CreateMaze

COSC 340: Software Engineering 31

slide-32
SLIDE 32

Abstract Factory Pattern: Maze Example

ConcreteFactory Implementations

COSC 340: Software Engineering 32

  • Subclass of MazeFactory
  • Overrides member functions and returns different instances of rooms and doors
slide-33
SLIDE 33

Abstract Factory Pattern: Maze Example

ConcreteFactory Implementations

COSC 340: Software Engineering 33

  • BombedMazeFactory ensures:
  • Walls are of class BombedWall
  • Rooms are of class RoomWithABomb
  • To build a simple maze with bombs,

call CreateMaze with BombedMazeFactory

slide-34
SLIDE 34

Abstract Factory Pattern: Maze Example

MazeFactory Implementation

COSC 340: Software Engineering 34

  • MazeFactory is a collection of factory methods
  • MazeFactory acts as both the AbstractFactory and a ConcreteFactory
slide-35
SLIDE 35

Prototype Pattern

  • Intent

‒ Specify the kinds of objects to create using a prototypical instance, and create new

  • bjects 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

slide-36
SLIDE 36

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

slide-37
SLIDE 37

Prototype Pattern: Example

Graphical Application for Editing Musical Scores

37

  • 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
slide-38
SLIDE 38

Prototype Pattern: Structure

COSC 340: Software Engineering 38

slide-39
SLIDE 39

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

slide-40
SLIDE 40

Prototype Pattern: Maze Example

COSC 340: Software Engineering 40

slide-41
SLIDE 41

Prototype Pattern: Maze Example

41

slide-42
SLIDE 42

Prototype Pattern: Maze Example

COSC 340: Software Engineering 42

  • Initialize with basic maze components to create a prototypical or default maze
slide-43
SLIDE 43

Prototype Pattern: Maze Example

COSC 340: Software Engineering 43

  • Initialize with bomb maze components to create a maze with bombs
slide-44
SLIDE 44

Prototype Pattern: Maze Example

44

  • Original definition for Door
  • Prototype pattern definition for Door
slide-45
SLIDE 45

Prototype Pattern: Maze Example

COSC 340: Software Engineering 45

  • 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
slide-46
SLIDE 46

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

slide-47
SLIDE 47

Composite Pattern

  • Compose objects into tree structures that let you treat individual
  • bjects and compositions of objects uniformly
  • Motivation

‒ Having to distinguish between primitive objects and compositions of primitive

  • bjects 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

slide-48
SLIDE 48

Composite Pattern: Motivation

Grouping Components in a Graphical Application

  • Graphics applications (e.g. drawing editors) often build diagrams out
  • f 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

slide-49
SLIDE 49

Composite Pattern: Motivation

Grouping Components in a Graphical Application

COSC 340: Software Engineering 49

slide-50
SLIDE 50

Composite Pattern: Structure

COSC 340: Software Engineering 50

slide-51
SLIDE 51

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

slide-52
SLIDE 52

Composite Pattern: Example

Electronic Equipment

COSC 340: Software Engineering 52

  • The Equipment class defines an interface for a hierarchy of electronic equipment
slide-53
SLIDE 53

Composite Pattern: Example

Electronic Equipment

COSC 340: Software Engineering 53

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

Composite Pattern: Example

Electronic Equipment

COSC 340: Software Engineering 54

  • CompositeEquipment is a base class for equipment that contains other equipment
slide-55
SLIDE 55

Composite Pattern: Example

Electronic Equipment

COSC 340: Software Engineering 55

  • Operations for CompositeEquipment are defined in terms of their children
slide-56
SLIDE 56

Composite Pattern: Example

Electronic Equipment

COSC 340: Software Engineering 56

  • Client code treats Equipment and CompositeEquipment objects in a uniform way
slide-57
SLIDE 57

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

slide-58
SLIDE 58

Adapter Pattern

  • 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

slide-59
SLIDE 59

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

slide-60
SLIDE 60

Adapter Pattern: Motivation

DrawingEditor Program

COSC 340: Software Engineering 60

slide-61
SLIDE 61

Adapter Pattern: Structure

Using Object Composition

COSC 340: Software Engineering 61

slide-62
SLIDE 62

Adapter Pattern: Structure

Using Multiple Inheritance

COSC 340: Software Engineering 62

slide-63
SLIDE 63

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

slide-64
SLIDE 64

Adapter Pattern: Sample Code

COSC 340: Software Engineering 64

slide-65
SLIDE 65

Adapter Pattern: Sample Code

Using Multiple Inheritance

COSC 340: Software Engineering 65

slide-66
SLIDE 66

Adapter Pattern: Sample Code

Using Multiple Inheritance

66

slide-67
SLIDE 67

Adapter Pattern: Sample Code

Using Object Composition

COSC 340: Software Engineering 67

slide-68
SLIDE 68

Adapter Pattern: Sample Code

Using Object Composition

COSC 340: Software Engineering 68

slide-69
SLIDE 69

Decorator Pattern

  • 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

slide-70
SLIDE 70

Decorator Pattern: Example

aTextView with aScrollDecorator and aBorderDecorator

COSC 340: Software Engineering 70

slide-71
SLIDE 71

Decorator Pattern: Example

aTextView with aScrollDecorator and aBorderDecorator

COSC 340: Software Engineering 71

slide-72
SLIDE 72

Decorator Pattern: Structure

COSC 340: Software Engineering 72

slide-73
SLIDE 73

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

slide-74
SLIDE 74

Decorator Pattern: Sample Code

COSC 340: Software Engineering 74

  • VisualComponent is the Component abstract base class
slide-75
SLIDE 75

Decorator Pattern: Sample Code

COSC 340: Software Engineering 75

  • 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

slide-76
SLIDE 76

Decorator Pattern: Sample Code

COSC 340: Software Engineering 76

  • Subclasses of Decorator define specific decorations
slide-77
SLIDE 77

Decorator Pattern: Sample Code

COSC 340: Software Engineering 77

  • Placing a TextView into the window with no decoration
slide-78
SLIDE 78

Decorator Pattern: Sample Code

COSC 340: Software Engineering 78

  • Adding a TextView with border and scrolling capabilities
slide-79
SLIDE 79

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

slide-80
SLIDE 80

Singleton Pattern

  • 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

  • ne 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

slide-81
SLIDE 81

Singleton Pattern Implementation:

Ensuring a Unique Instance

COSC 340: Software Engineering 81

slide-82
SLIDE 82

Singleton Pattern Implementation:

Ensuring a Unique Instance

COSC 340: Software Engineering 82

  • 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
  • f the Singleton type
  • Runtime initialization allows you to

define when the object is initialized

slide-83
SLIDE 83

Singleton Pattern Example: MazeFactory

COSC 340: Software Engineering 83

slide-84
SLIDE 84

Singleton Pattern Example: MazeFactory

COSC 340: Software Engineering 84

slide-85
SLIDE 85

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

slide-86
SLIDE 86

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

slide-87
SLIDE 87

Template Method Pattern

  • 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

slide-88
SLIDE 88

Template Method Pattern: Example

Application Framework with Application and Document classes

COSC 340: Software Engineering 88

slide-89
SLIDE 89

Template Method Pattern: Example

Application Framework with Application and Document classes

COSC 340: Software Engineering 89

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

Template Method Pattern: Structure

COSC 340: Software Engineering 90

slide-91
SLIDE 91

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

slide-92
SLIDE 92

Observer Pattern

  • 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

slide-93
SLIDE 93

Observer Pattern: Example

Model and View Components

COSC 340: Software Engineering 93

  • 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
slide-94
SLIDE 94

Observer Pattern: Structure

COSC 340: Software Engineering 94

slide-95
SLIDE 95

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

slide-96
SLIDE 96

Observer Pattern: Collaborations

COSC 340: Software Engineering 96

slide-97
SLIDE 97

Observer Pattern: Sample Code

COSC 340: Software Engineering 97

  • Abstract class for the Observer interface
  • Supports multiple subjects for each observer
slide-98
SLIDE 98

Observer Pattern: Sample Code

98

  • Abstract class for the Subject interface
slide-99
SLIDE 99

Observer Pattern: Sample Code

COSC 340: Software Engineering 99

  • ClockTimer is a concrete subject for

maintaining the time of day

  • Tick is called by an internal timer at

regular intervals

slide-100
SLIDE 100

Observer Pattern: Sample Code

COSC 340: Software Engineering 100

  • DigitalClock class for displaying the time
slide-101
SLIDE 101

Observer Pattern: Sample Code

101

  • Constructor and destructor attach and

detach the DigitalClock from its subject

  • On update, draw the digital clock with

the updated hour and minute

slide-102
SLIDE 102

Observer Pattern: Sample Code

COSC 340: Software Engineering 102

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

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

slide-104
SLIDE 104

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

slide-105
SLIDE 105

Observer Pattern: Implementation Issues

Encapsulating complex update semantics

105

  • DAGChangeManager handles DAGs of dependencies between subjects and observers
  • Avoids redundant updates when observers have multiple subjects
slide-106
SLIDE 106

Iterator Pattern

  • 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

slide-107
SLIDE 107

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

slide-108
SLIDE 108

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

slide-109
SLIDE 109

Iterator Pattern: Example

List class with a ListIterator

109

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

Iterator Pattern: Structure

COSC 340: Software Engineering 110

slide-111
SLIDE 111

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

slide-112
SLIDE 112

Iterator Pattern: Sample Code

Interface Definitions

COSC 340: Software Engineering 112

  • List interface
  • Iterator interface
slide-113
SLIDE 113

Iterator Pattern: Sample Code

Concrete ListIterator Definition

COSC 340: Software Engineering 113

slide-114
SLIDE 114

Iterator Pattern: Sample Code

Concrete ListIterator Definition

COSC 340: Software Engineering 114

slide-115
SLIDE 115

Iterator Pattern: Sample Code

Using the Iterators

COSC 340: Software Engineering 115

slide-116
SLIDE 116

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

slide-117
SLIDE 117

Backup

COSC 340: Software Engineering 117

slide-118
SLIDE 118

Implementation:

Subclassing the Singleton Class

118

slide-119
SLIDE 119

Registering the Singleton

COSC 340: Software Engineering 119

  • Where do you call the constructor?
  • Define a static instance in the file that contains the subclass implementation
  • Register singletons in the constructor of the subclass
slide-120
SLIDE 120

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

slide-121
SLIDE 121

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

slide-122
SLIDE 122

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

slide-123
SLIDE 123

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

slide-124
SLIDE 124

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

slide-125
SLIDE 125

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

slide-126
SLIDE 126

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

slide-127
SLIDE 127

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

  • f state

COSC 340: Software Engineering 127

slide-128
SLIDE 128

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

slide-129
SLIDE 129

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

slide-130
SLIDE 130

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
  • Strategy pattern forwards component behavior to a separate strategy object
slide-131
SLIDE 131

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

slide-132
SLIDE 132

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

slide-133
SLIDE 133

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

slide-134
SLIDE 134

Flyweight Pattern

  • 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

slide-135
SLIDE 135

Flyweight Pattern: Example

Graphical Representation of Characters in a Word Processor

COSC 340: Software Engineering 135

  • Word processor application
  • Uses objects to represent embedded

elements (tables, figures)

  • Objects for each character?
  • Allows you to treat drawing of characters,
  • ther elements uniformly
  • Easy to extend with new character sets

without disturbing other functionality

  • Cost could be prohibitive
slide-136
SLIDE 136

Flyweight Pattern: Example

Graphical Representation of Characters in a Word Processor

COSC 340: Software Engineering 136

  • 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
slide-137
SLIDE 137

Flyweight Pattern: Example

Graphical Representation of Characters in a Word Processor

COSC 340: Software Engineering 137

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

Flyweight Pattern: Example

Graphical Representation of Characters in a Word Processor

COSC 340: Software Engineering 138

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

Flyweight Pattern: Example

Graphical Representation of Characters in a Word Processor

COSC 340: Software Engineering 139

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

Flyweight Pattern: Example

Graphical Representation of Characters in a Word Processor

COSC 340: Software Engineering 140

  • 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

slide-141
SLIDE 141

Flyweight Pattern: Structure

Class Diagram

COSC 340: Software Engineering 141

slide-142
SLIDE 142

Flyweight Pattern: Structure

How Flyweight Objects are Shared

COSC 340: Software Engineering 142

slide-143
SLIDE 143

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

slide-144
SLIDE 144

Flyweight Pattern: Sample Code

COSC 340: Software Engineering 144

  • Flyweight base class
slide-145
SLIDE 145

Flyweight Pattern: Sample Code

COSC 340: Software Engineering 145

  • Character subclass stores a character code
slide-146
SLIDE 146

Flyweight Pattern: Sample Code

COSC 340: Software Engineering 146

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

Flyweight Pattern: Sample Code

COSC 340: Software Engineering 147

  • _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
slide-148
SLIDE 148

Flyweight Pattern: Sample Code

_fonts BTree Example

COSC 340: Software Engineering 148

  • 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
slide-149
SLIDE 149

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

slide-150
SLIDE 150

Flyweight Pattern: Sample Code

_fonts BTree Example

COSC 340: Software Engineering 150

  • BTree is updated to indicate "expect" is the same font as the surrounding words
slide-151
SLIDE 151

Flyweight Pattern: Sample Code

COSC 340: Software Engineering 151

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

Flyweight Pattern: Sample Code

COSC 340: Software Engineering 152

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

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

slide-154
SLIDE 154

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

slide-155
SLIDE 155

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

155

  • Derived classes always have to remember

to call ParentClass::Operation

  • ParentClass uses TM with a hook operation to

Ensure parent and derived operations are called together

slide-156
SLIDE 156

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