Design patterns - PowerPoint PPT Presentation

1 / 209
About This Presentation
Title:

Design patterns

Description:

{ Creator myCreator = new GenericCreator ProductA ... many applications, we don't change just one type of object, but, rather, a family of objects ... – PowerPoint PPT presentation

Number of Views:34
Avg rating:3.0/5.0
Slides: 210
Provided by: mch6
Category:

less

Transcript and Presenter's Notes

Title: Design patterns


1
Design patterns
  • What is a pattern?
  • Pattern describes a problem which occurs over and
    over again in our environment, and then describes
    the core of the solution to that problem, in such
    a way that you can use this solution a million
    times over , . . .
  • Christopher Alexander (architecture
    theorist)

2
Patterns are common
  • Design catalogs
  • Script writers
  • Fashion designers
  • Interior designers
  • Architects
  • Patterns are common tricks used by the profession
  • Dont reinventing the wheel
  • Simply copy a proven design

3
Design Pattern by Gamma et al
  • 23 common design patterns divided into 3 groups
  • How to create objects (creational patterns)
  • How to group them (structural patterns)
  • How to use them (behavior patterns)
  • Two general approaches in patterns
  • Class inheritance
  • Object delegation

4
  • Each pattern has
  • Name
  • Problem statement
  • Solution
  • Consequences
  • Importance of the name
  • To facilitate communication between developers

5
Exercises
  • Simple quiz
  • http//home.earthlink.net/huston2/dp/patterns_qui
    z.html
  • A list of open-end questions
  • http//www.industriallogic.com/papers/learning.htm
    lQUESTIONS

6
Two fundamental principles in OO Programming
  • Programming to an Interface, not an
    Implementation
  • so that you can change the implementation easily
    in future, the interface is just like a socket
  • Favour object composition over class inheritance
  • To promote more flexible reuse
  • Dont overuse inheritance (only for classes that
    share the same behavior)

7
Example Maze game
  • To write a maze adventure game
  • The game
  • A maze has-a number of rooms
  • A room has four sides (North, East, South, West)
  • A player enters a side
  • If the side is a door, it leads to another room
  • If the side is a wall, the player is hurt
  • The player wins if a way leaving the maze is found

8
The objects
  • MazeGame, Maze, Room, Door, Side
  • Polymorphism
  • Group Room, Door and Side under the abstract base
    class MapSite
  • Base class virtual function
  • Enter()
  • How to build the maze using OO concepts?

9
Is-a relation
  • A Room is-a kind of MapSite
  • A Door is-a kind of MapSite
  • A Wall is-a kind of MapSite
  • Is-a suggests class inheritance

MapSite
Is-a
Room
Door
Wall
10
Is-a relation
  • Skeleton code
  • class MapSite //ABSTRACT class
  • public virtual void Enter()
  • class Room MapSite //CONCRETE class
  • public override void Enter()
    //implementation
  • Room.Enter() - enter a room
  • Door.Enter() - enter the room beyond the door
  • Wall.Enter() - get hurt, stay at the same room

11
Has-a relation
  • A maze has-a number of rooms
  • A room has four sides
  • A room may have several smaller rooms
  • Has-a suggests object composition

12
A UML diagram describing the maze structure
Recursion. Known as Composite pattern
MapSite Enter()
Has-a
Room Enter() SetSide() GetSide() RoomNo
Wall Enter()
Door Enter()
rooms
Maze AddRoom() RoomNo() ArrayList _rooms
Has-a
13
Object composition
  • Maze is composed of (has-a) Rooms
  • Room is composed of Doors, Walls and Rooms.
  • class Maze
  • private ArrayList _roomsnew ArrayList()
  • //a typeless container that holds the rooms
  • class Room MapSite
  • public override void Enter() //. . .
  • private MapSite _sides new MapSite4

14
Wall, Door
  • class Wall MapSite
  • public override void Enter() . . .
  • class Door MapSite
  • private Room _room1
  • private Room _room2
  • public Door(Room r1, Room r2) . . .
  • public override void Enter() . . .
  • static void Main()
  • . . .
  • MazeGame game new MazeGame()
  • _aMaze game.CreateMaze() //create the
    maze
  • . . .

15
MazeGame.CreateMaze() creates a simple maze
N
Room 2
Room 1
aWall
Objects structure
aDoor(r1,r2)
_aMaze _rooms
aWall
r2 . . .
aWall
16
  • Maze MazeGame.CreateMaze()
  • Maze aMaze new Maze() //create a maze
    object
  • Room r1 new Room(1) //create rooms
  • Room r2 new Room(2)
  • Door theDoor new Door(r1, r2) //create door
  • r1.SetSide(North, new Wall()) //add wall to
    room
  • r1.SetSide(East, theDoor()) //add door to
    room
  • r1.SetSide(South, new Wall())
  • r1.SetSide(West, new Wall())
  • // . . . init r2 like r1
  • aMaze.AddRoom(r1) //add to container
  • aMaze.AddRoom(r2)
  • return aMaze

17
What is wrong with CreateMaze()?
MazeGame Maze MazeGame.CreateMaze() Maze
aMaze new Maze() Room r1 new
Room(1) Room r2 new Room(2) Door theDoor
new Door(r1, r2) . . . return aMaze
18
What if . . .
  • in future, we would like
  • to CREATE a different kind of room?
  • to CREATE a different kind of door?
  • to CREATE a different kind of wall?
  • We need to change the code in CreateMaze()

19
This is what we have to do break the old code !
MazeGame Maze MazeGame.CreateMaze() Maze
aMaze new Maze() Room r1 new
EnchantedRoom(1) Room r2 new
EnchantedRoom(2) Door theDoor new
DoorNeedSpell(r1, r2) return aMaze
20
Solutions?
  • Class inheritance
  • Factory method
  • Object delegation
  • Abstract factory
  • Builder
  • Prototype

21
Factory method
  • Replace new by virtual function
  • Virtual function can be overrided by the
    subclass, so that different objects can be created

MazeGame Maze MazeGame.CreateMaze() Room
r1 MakeRoom(1) //. . . //base class
default MakeRoom() Room MazeGame.MakeRoom(int n)
return new Room(n)
22
Let subclass to override the factory method
MazeGame Maze MazeGame.CreateMaze() Room
r1 MakeRoom(1)
EnchantedMazeGame //override base class
MakeRoom() Room EnchantedMazeGame.MakeRoom(int
n) return new EnchantedRoom(n, SpellDoor())

23
Change one line and have a different MazeGame
  • public class Form1 Form
  • Maze _aMaze
  • static void Main()
  • using (Form1 form new Form1())
  • form.InitializeGame()
  • Application.Run(form)
  • private void InitializeGame()
  • //MazeGame game new MazeGame()
  • MazeGame game new EnchantedMazeGame()
  • _aMaze game.CreateMaze() //create the
    maze
  • //. . . code for the event handlers

24
Factory Method
  • Define an interface (the virtual functions) for
    creating an object, but let subclasses decide
    which class to instantiate.
  • Factory Method lets a class defer instantiation
    to subclasses.
  • Also known as virtual constructor

25
Framework, toolkit and application
  • What is the difference between framework, toolkit
    and application?
  • Framework has the highest degree of reuse, and is
    the most flexible
  • Application is the least flexible

26
What is a framework?
  • A framework is an abstract type of software that
    captures the design decisions that are common to
    its application domains
  • e.g. what is the similarity between a circuit
    design editor, and musical score editor?
  • Both manipulate graphical objects
  • An abstract software (framework) that can support
    both applications?

27
A general framework for graphical processing
Framework
AbstractFramework NewDoc() AbstractGraphic g g
CreateGraphic()
AbstractGraphic Move() Scale()
MyGraphic
MyGraphicApplication CreateGraphic() //factory
method return new MyGraphic()
28
A framework for graphical processing
  • The concrete MyGraphic object can be any graphic
    symbols, e.g. musical notes, circuit symbols
  • These objects can be manipulated by a uniform set
    of operations (e.g. Move(), Scale(), etc)
  • Code in framework knows how to manipulate the
    abstract base class AbstractGraphic object
  • The concrete subclass object (MyGraphic ) is
    created differently for different application

29
A musical score editor
Framework
AbstractFramework NewDoc() AbstractGraphic g g
CreateGraphic()
AbstractGraphic Move() Scale()
MyMusicScore
MyMusicScoreApplication CreateGraphic() //factory
method return new MyMusicScore()
30
A electronic circuit editor
Framework
AbstractFramework NewDoc() AbstractGraphic g g
CreateGraphic()
AbstractGraphic Move() Scale()
MyCircuit
MyCircuitApplication CreateGraphic() //factory
method return new MyCircuit()
31
  • Thinking in two levels
  • Abstract level (framework level)
  • I (framework) dont care what the symbols
    (objects) are about !
  • My job is just to move, to scale, to draw, and to
    print the symbols
  • How to draw/print the symbols? That is the job of
    the symbols themselves (think like a boss!)
  • Concrete level
  • All the (dirty) real work is done by me (concrete
    objects)

32
What is a framework?
  • Framework emphasizes design reuse rather than
    code reuse
  • Framework contains the main program, users
    customize the framework by providing the concrete
    subclasses
  • Modern systems have layers of frameworks that
    cooperate with each other

33
Toolkit
  • Toolkit is just a set of reusable classes,
    providing the functionality
  • Emphasize code reuse
  • Users write the main program, toolkit provides
    reusable code
  • Framework is harder to code than toolkit
  • Toolkit is harder to code than application

34
Pros and cons of class inheritance
  • Pros
  • Simpler than object delegation, codes are easier
    to follow
  • Cons
  • Static binding, fixed at compilation time, cannot
    be changed at run-time
  • Need to create new subclass
  • Ways to reduce the number of subclasses?

35
Parameterized factory methods
  • The method takes a parameter that identifies the
    kind of product
  • Parameterized factory methods reduce the number
    of subclasses that are needed
  • Use
  • In document applications, different document type
    has different file extent (.doc, .xml, .txt, . .
    .)

36
Parameterized factory methods
  • class Creator
  • public virtual Product Create(int id)
  • class ConcreteCreator Creator
  • public override Product Create(int id)
  • if (idA) return new ProductA
  • if . . .
  • return base.Creator(id)

37
Use Generic to avoid subclassing
  • Problem with factory methods
  • For every new product, you need to subclassing
    the Creator for creating the product
  • Use Generics to void subclassing
  • The code for the subclass is automatically
    generated by the compiler
  • In the following example, GenericCreatorltTgt is
    just a template, compiler uses it to generate the
    code

38
Use Generic to avoid subclassing
  • class Creator
  • public virtual Product Create()
  • class GenericCreatorltTgt Creator
  • public override Product Create()
  • return new T()
  • Main()
  • Creator myCreator new GenericCreatorltProductAgt
    ()
  • Product p myCreator.Create() //factory
    method

39
The code generated
  • class GenericCreator Creator
  • public override Product Create()
  • return new ProductA()

40
Create objects by Object Delegation
MazeGame CreateMaze(f) //f is a factory
object Maze aMaze new Maze() Room r1
f.MakeRoom(1) Room r2 f.MakeRoom(2) //. .
. return aMaze
AbstractFactory MakeRoom(int n)
delegate
ConcreteFactory MakeRoom(int n) return new
Room(n)
MakeRoom is a factory method
41
Abstract Factory
  • In many applications, we dont change just one
    type of object, but, rather, a family of objects
  • This can be done by using a factory object
  • To select a different game at run-time
  • Just change the (concrete) factory object f
  • Abstract Factory provides an interface for
    creating families of related or dependent objects
    without specifying their concrete classes

42
Example - the Look-and-Feel Problem
  • How to change the look and feel of the desktop at
    run-time?
  • e.g. change to MotifWindow, MSWindow,
    AppleWindow
  • Solution
  • Choose a concrete factory object
  • MotifFactory, MSFactory, or AppleFactory
  • The factory object creates the concrete products
  • MSWindow, MSScrollBar, . . .)
  • but returns them as abstract products
  • Window, ScrollBar

43
Abstract Factory client uses an abstract
factory GUIFactory to produce abstract products
delegate
GUIFactory CreateScrollBar() CreateWindow()
client
Window
Is-a
Is-a
MSWindow
MotifWindow
MotifFactory CreateScrollBar() CreateWindow()
ScrollBar
MSFactory CreateScrollBar() CreateWindow()
MSScrollBar
MotifScrollBar
44
Abstract Factory
  • GUIFactory guifactory
  • //choose a concrete factory object
  • if (strcmp( inputName, Motif) 0 )
  • guifactory new MotifFactory()
  • else
  • guifactory new MSFactory()
  • //factory returns abstract product
  • Window w guifactory.CreateWindow()
  • w.Draw()

Different factory creates different concrete
product
Return the abstract product, upcasting,
polymorphism
45
Builder
  • Problem
  • To build a complex object, e.g. a building, an
    aircraft
  • The complex object has different representations
  • i.e. we can look at the object at different ways
  • e.g. different representations of an aircraft
  • Its look
  • Its total weight
  • Its total cost

46
Builder
  • What to reuse?
  • The construction of the object is complex
  • Want to reuse the construction process so as to
    create different representations
  • Solution?
  • Separate the construction of a complex object
    from its representation so that the same
    construction process can create different
    representations

47
Builder
Construction
MazeGame CreateMaze(builder)
builder.BuildMaze() builder.BuildRoom(1)
builder.BuildRoom(2) //. . . return
builder.GetMaze()
AbstractBuilder buildRoom(int n)
delegate
ConcreteBuilder buildRoom(int n) return new
Room(n)
Representation
48
Builder
  • Change the concrete Builder, get a different
    product
  • Example
  • CountBuilder
  • To count the number of parts (rooms, doors) used
    in the maze
  • SimpleBuilder
  • Return a simplified graphical maze object that is
    good for low-end mobile phone

49
Intent and its importance
  • Abstract Factory and Builder are different
    patterns for solving different problems
  • But they have the same code structure !!
  • They have the same UML diagrams
  • Code is not everything
  • Should also know the intent of the code

50
Difference between Abstract Factory and Builder
  • Their intent are different
  • Abstract Factory
  • Provide an interface for creating families of
    related or dependent objects without specifying
    their concrete classes
  • Builder
  • Separate the construction of a complex object
    from its representation so that the same
    construction process can create different
    representations

51
Abstract Factory and Builder
  • Abstract Factory focuses on building a families
    of parts (either simple or complex), and returns
    the part immediately
  • Client assembles the parts into complex object
  • Builder returns the product as a final step
  • The concrete parts in the complex object is
    encapsulated inside the Builder
  • Parts have different representations that are
    hidden from the client
  • Appearance, weight, cost, . . .
  • Change Builder, change representation

52
Problem
  • To build a maze that allows player to choose the
    composition of the maze at run-time
  • e.g. the maze can be made up of EnchantedRoom,
    DoorWithSpell and BombedWall
  • The problem is like creating an ice cream object
    with different combination of favours
  • Use a factory to build these parts so that player
    can choose the composition dynamically

53
Problem with subclassing
AbstractFactory
Factory1 Door Wall Room
Factory2 DoorWithSpell Wall Room
Factory3 Door BombedWall Room
Factory4 Door Wall EnchantedRoom
Factory5 DoorWithSpell BombedWall Room
Factory8 DoorWithSpell BombedWall EnchantedRoom
. . .
54
Combinatorial problem
  • If we have 5 different types of rooms, doors and
    walls, we have 555 different combinations
  • Need to create 125 subclasses !
  • Class explosion, a common problem with
    subclassing
  • A better approach - composition
  • Construct a prototype object at run-time
  • The prototype is composed of
  • EnchantedRoom, DoorWithSpell and BombedWall
  • Prototype is a factory object that manufactures
    the parts by cloning

55
The Prototype MazePrototypeFactory factory
  • class MazePrototypeFactory MazeFactory
  • public MazePrototypeFactory(Maze m, Wall w,
  • Room r, Door d)
  • public virtual Maze MakeMaze()
  • public virtual Room MakeRoom(int i)
  • public virtual Wall MakeWall()
  • public virtual Door MakeDoor(Room r1, Room r2)
  • private Maze _prototypeMaze
  • private Room _prototypeRoom
  • private Wall _prototypeWall
  • private Door _prototypeDoor

56
To create the prototype object
  • int Main()
  • MazeGame game
  • MazePrototypeFactory factory(new Maze(), new
    BombedWall(), new EnchantedRoom(), new
    DoorWithSpell())
  • Maze maze game.CreateMaze(factory)
  • . . .

Construct a Prototype factory object
factory Maze _maze new Maze() Wall _wall new
BombedWall() Room _room new EnchantedRoom() Door
_door new DoorWithSpell()
57
The prototype constructor
  • Create the prototype object by composition
  • MazePrototypeFactory(Maze m, Wall w, Room r, Door
    d)
  • _maze m //point to an concrete object
  • _wall w
  • _room r
  • _door d

Has-a relation (a prototype has-a maze, wall,
room and door) Also known as composition
58
How to use it?
  • We use the prototype factory object like an
    Abstract Factory object
  • Maze MazeGame.CreateMaze(MazeFactory factory)
  • Maze aMaze factory.MakeMaze()
  • Room r1 factory.MakeRoom(1)
  • . . .
  • So what is inside factory.MakeRoom()?

59
How to use it?
  • factory.MakeRoom() uses the existing Room object
    to clone a new EnchantedRoom

Room Room Clone()
createMaze(factory) r1factory.MakeRoom(1)
MazeFactory
MazePrototypeFactory private Room _room Room
MakeRoom(int i) r_room.Clone() r.Number
i return r
EnchantedRoom Room Clone() Room rnew
EnchantedRoom() //copy attributes from this
return r
A clone of EnchantedRoom
60
Summary Creational Patterns
  • Factory Method Define an interface for creating
    an object, but let subclasses decide which class
    to instantiate. Factory Method lets a class defer
    instantiation to subclasses
  • Abstract Factory Provide an interface for
    creating families of related or dependent objects
    without specifying their concrete classes
  • Builder Separate the construction of a complex
    object from its representation so that the same
    construction process can create different
    representations
  • Prototype Specify the kinds of objects to create
    using a prototypical instance, and create new
    objects by copying this prototype

61
Singleton
  • How to create one and only one instance of a
    class,
  • e.g. a single print queue shared by many printer
  • a single window server for the user interface
  • The single object must be easily accessible
  • Intent
  • Ensure a class only has one instance, and provide
    a global point of access to it

62
The consideration
  • To make the object easily accessible
  • Use a global/static object
  • Drawback
  • No guarantee that there is only one instance of
    the class, e.g.
  • static Singleton object_1 new Singleton()
  • static Singleton object _2 new Singleton()
  • Problem - two objects of the same class
  • Solution - use a private constructor !

63
Use private constructor and public method
  • sealed class Singleton
  • protected Singleton()
  • private static Singleton _instancenull
  • public static Singleton Instance()
  • if (_instancenull)
  • _instance new Singleton()
  • return _instance
  • Main() //to use a Singleton
  • Singleton server1 Singleton.Instance()
  • Singleton server3 new Singleton()
  • //wont compile, constructor is protected

64
  • Singleton() is private object can only be
    created via the function Instance()
  • Instance()controls the number of objects created
  • But Instance()is an object level method
  • With a private constructor, we have a problem in
    creating the first object
  • Without an object, we cannot invoke Instance()
  • Instance() must therefore be a class level
    (static) method

65
  • Creational patterns
  • Create objects flexibly
  • Structural patterns
  • Group objects together to form more complex
    structure

66
Adapter
  • Problem
  • A bank is developing a new system with a new
    interface, how to reuse the old (legacy) system ?

client
INewSystem NewRequest()
OldSystem OldRequest()
67
  • Solution

Class Adapter
Object Adapter
Old
New
New
Old
ClassAdapter
ObjectAdapter
68
Class Adapter - by class inheritance
client
INewSystem NewRequest()
OldSystem OldRequest()
69
Class Adapter
  • public class ClassAdapter OldSystem, INewSystem
  • public void INewSystem.Request()
  • base.OldRequest() //base refers to OldSystem
  • Main()
  • INewSystem sys new ClassAdapter()

70
Problems
  • Modern OO languages (C, Java) only support
    single implementation inheritance
  • Cannot hide the old implementation
  • Interface in OldSystem can be exposed by casting
  • class ClassAdapter private OldSystem,
    INewSystem
  • Object Adapter does not have these problems

Ideal, but not supported in C
71
Object Adapter
client
NewSystem NewRequest()
OldSystem OldRequest()
adaptee
Object Adapter NewRequest()
adaptee-gtOldRequest()
72
Object Adapter
  • public class ObjectAdapter NewSystem
  • private OldSystem _oldSys new OldSystem()
  • public void NewRequest()
  • _oldSys.OldRequest() //delegation
  • Single implementation inheritance
  • Interface of the old system is hidden from client

73
Adapter
  • Also Known as
  • Wrapper
  • Intent
  • Convert the interface of a class into another
    interface clients expect.
  • Adapter lets classes work together that couldnt
    otherwise because of incompatible interfaces

74
Problem
  • To support a computer game for two different
    hardware platforms
  • Solution by subclassing

Game
abstraction
implementations
XBoxGame
PSGame
75
Bridge
  • Problem with extending the abstraction
  • To add a platform (Nokia phone), need to port the
    implementation of the game to the new platform
  • A better solution
  • Separate the platform-specific code from the
    abstraction (of the game)

76
Bridge
  • Decouple (separate) an abstraction from its
    implementation so that the two can vary
    independently

imp
Implementor Operation()
Abstraction
imp.Operation()
Imp_1
Abstract_2
Abstract_1
Imp_2
Imp_3
77

Abstraction Implementation
GameImp DevDrawText() DevDrawLine()
Game DrawText() DrawRect() GameImp imp
imp
imp.DevDrawLine()
ConcreteGame1 DrawBorder()
PSImp
XBoxImp
DrawRect() DrawText()
78
Bridge
  • IntentDecouple an abstraction from its
    implementation so that the two can vary
    independently
  • The Graphics object in GDI is an example of
    Bridge pattern
  • GDI, platform specific code is separated and
    encapsulated in a Graphics object
  • Different Graphics object can be used to
    represent different graphic card

79
Composite
  • A graphics application has primitives (line,
    circle), which can be grouped to form a larger
    component
  • Component is just a container
  • Components can be grouped to form an even larger
    components
  • Problem
  • How to treat primitives and components uniformly
  • e.g. if g is a line, g.Draw() will draw a line
  • if g is a component, g.Draw() will draw all the
    composition recursively

80
Composite
  • Uniform interface - suggest the use of a base
    class

Graphic Draw()
Picture Draw()
Circle Draw()
Line Draw()
81
Composite
  • A Picture is a Composite (has-a
    pictures/primitives)
  • Recursion

Graphic Draw()
Picture Draw()
Circle Draw()
Line Draw()
82
  • Recursive object structure

aPicture
aLine
aCircle
aPicture
aLine
aCircle
aPicture
83
Composite code example
  • class Graphic
  • public virtual void Draw()
  • //. . .
  • class Picture Graphic
  • private ArrayList graphics //container
  • public void Draw()
  • foreach (object o in ArrayList)
  • Graphic g (Graphic) o
  • g.Draw() //if g is-a line, draw line
  • //if g is-a picture, recursion

84
Composite
  • Intent
  • Compose objects into tree structures to represent
    part-whole hierarchies. Composite let clients
    treat individual objects and compositions of
    objects uniformly
  • Note
  • Part-whole hierarchies are extremely common,
    making Composite one of the most useful pattern

85
Decorator
  • Problem
  • How to create a reader object that can
  • Read a stream from the file
  • Decrypt the stream
  • Perform a formatted read (read an integer,
    double, etc, from byte stream)
  • How to build this reader object flexibly?

86
Class inheritance approach
  • Create more specialized objects by subclassing
  • The concrete BinaryRead object
  • use FileStream code to read the file
  • use CryptoStream code to decrypt the file
  • use its own code to do formatted read

FileStream
CryptoStream
BinaryReader
87
Class inheritance approach
  • Combinatorial problem, need many subclasses
  • Static binding cant change at run-time
  • Object delegation
  • More flexible than by subclassing
  • Concept is similar to piping in Unix, a complex
    object is formed by joining several objects
    together

Structure of a decorator
88
Decorator
  • To create new object by composition and perform a
    chain of actions
  • FileStream.Read() then CryptoStream.Read()
    then BinaryReader.ReadXxx()

A decorator object
CryptoStream Read() Stream _next
FileStream Read() Stream _next
BinaryReader ReadXxx() Stream _next
89
Decorator object diagram
Has-a relationship Software piping by delegation
BinaryReader Stream _next ReadXxx() if
(!_next) _next.Read() //format data

CryptoStream Stream _next Read() if (!_next)
_next.Read() //decrypt data
FileStream Read() //read data
90
Decorator class diagram
  • To support composition of indefinite number of
    objects

Stream Read(byte buffer, int offset, int count)
1
ConcreteStream Read(. . .) Stream _next
Has-a
91
Class diagram of System.IO in C
Reader has the same class diagram as Writer
TextWriter
BinaryWriter
Stream
StreamWriter
StringWriter
CryptoStream
FileStream
BufferStream
NetworkStream
Note the decorator pattern
92
The structure of the IO design
  • TextWriter class
  • For writing characters
  • StreamWriter for writing a indefinite sequence
    of characters
  • BinaryWriter class
  • Class for writing a binary stream
  • Stream class
  • For adding different features flexibly using the
    decorator pattern

93
Example
  • An object that formats, encrypts, and writes to
    file
  • using System
  • using System.IO
  • using System.Security.Cryptography
  • static void Main(string args)
  • //initialization code skipped
  • FileStream fout new FileStream(. . .)
  • CryptoStream cs new CryptoStream(fout, . . . )
  • BinaryWriter bw new BinaryWriter(cs)
  • bw.Write("hello world")//format, encrypted,
    write to file
  • bw.Close()
  • cs.Close()
  • fout.Close()

94
Decorator
  • Also known as
  • Wrapper
  • Intent
  • Attach additional responsibilities to an object
    dynamically.
  • Decorators provide a flexible alternative to
    subclassing for extending functionality
  • Known Uses
  • I/O objects in C, Java
  • graphical user interface (see text)

95
Façade
  • Problem
  • Objects have too many dependency, how to reduce
    the dependency?

Subsystem
96
Façade
  • Solution
  • Create Subsystem with a single and unified
    interface

Facade
Subsystem
97
Façade
  • Intent
  • Provide a unified interface to a set of
    interfaces in a subsystem. Façade defines a
    higher-level interface that makes the subsystem
    easier to use
  • Façade objects are often Singletons
  • C internal keyword
  • A subsystem has public classes and encapsulated
    private classes
  • Use internal keyword for encapsulating classes
    within an assembly, and public keyword for the
    Façade public class

98
Proxy
  • Problem
  • Some objects are expensive to create
  • e.g. a large document with many objects (text,
    images)
  • Create all the objects at once takes too long
  • Solution
  • Create a proxy object quickly
  • Only create the objects when they are needed
    (visible in the document)

Proxy
99
Proxy
  • ImageProxy is an object that can be created very
    cheaply, it maintains a reference to the image on
    disk

aTextDocument image
anImageProxy fileName
anImage data
in memory
on disk
100
Image Proxy
Graphic Draw()
client
realSubject
ImageProxy Draw() Image image
Image Draw()
(has-a)
//draw only on-demand if(image 0)
imageLoadImage(fileName) image.Draw()
101
Proxy server example
WebServer Get(url) . . .
client
WebProxy Get(url) . . .
OriginServer Get(url) . . .
//get over the net only on-demand if(
url_not_in_cache ) urlserver.Get(url) retu
rn url
102
Proxy application
  • virtual proxy (as in our example)
  • creates expensive objects on demand
  • e.g. virtual memory in an OO Unix
  • remote proxy
  • provides a local representative for an object in
    a different address space (e.g CORBA, RMI, .NET)
  • protection proxy
  • control access to the original object
    (authentication)
  • smart reference
  • replacement of a bare pointer that performs
    additional actions, e.g. web page filtering

103
Flyweight
  • A pattern for system that has a large number of
    tiny objects
  • Scenario
  • In a word processing application, we have
  • row objects
  • column objects
  • character objects
  • A column may have several rows, and each row may
    have many character objects
  • Use Composite Pattern to model this structure

104
Flyweight
  • Composite Pattern
  • All objects are treated uniformly by the
    functions provided in base class Glyph
  • Captures the tree-structure of the document

Glyph
Glyph
Row
column
105
Flyweight
  • Problem
  • Large number of small objects !
  • One page 500 words 2500 characters (objects)

106
Flyweight
  • Solution
  • Each character object is a singleton shared in a
    pool

107
An object has
  • Sharable attributes
  • e.g. the character code
  • Non-sharable attributes
  • e.g. font type and font size
  • Sharable attributes are stored in Singleton
    objects, located in a sharable flyweight pool
  • The non-sharable attributes are stored in a
    context object (GlyphContext)
  • Example of non-sharable context
  • font size, font type

108
Represent the context by a table
  • The table can be implemented using Dictionary
    that supports the IDictionary interface
  • Dictionary has a collection of key/value pairs
  • Key position, stringcontext
  • int(key) string(value)
  • Times 24 //1 char
  • Times 12 //next 100 char
  • Times-Italic 12 //next 6 char
  • Times 12 //next 194 char
  • . . .

109
Flyweight
  • To draw a Character object
  • Glyph.Draw() is not enough
  • Character contains only the sharable attributes,
    need the GlyphContext object to get the context
  • Glyph.Draw(GlyphContext)
  • complete information Glyph GlyphContext

110
  • Creational patterns
  • How to create objects flexibly
  • Structural patterns
  • How to group objects together
  • Behavioral patterns
  • How to use objects in a collaborative way
  • The key - identify the responsibilities of the
    objects

111
Course Registration System
  • Design a course registration system to support
  • Course browsing
  • Course registration
  • Constraint checking (e.g. pre-requisite)
  • Course functions (e.g. print course list)
  • Problem
  • What is the object structure that we should use?

112
  • Arrange the courses by a tree structure

university
Science
Engineering
Law
IE
composite
CSE
leaf
IEG3080
113
Composite pattern
Node string _name
NodeList //nameErg,Sci,...
Course //nameIEG3080 ...
114
Problem - GUI framework to support course
browsing?
Menu bar
Course Info
Registration
ALL ART MED SCI
Menu
ACE CE CS EE SEEM
ERG
Menu item
IE
IEG1110 IEG2220 . . .
IEG3080
115
Browsing
ALL ART ERG MED SCI
  • The menu
  • Menu item
  • ALL, ART, ERG, . . ., IE, . . ., IEG3080
  • Each item has a different Action
  • ALL will list all courses provided
  • ART will list all courses in ART faculty
  • IEG3080 will list course info in IEG3080

116
  • A GUI framework can only provide the following
    abstract widgets
  • Menu
  • MenuItem
  • A Menu has-a number of MenuItems
  • Select a MenuItem, an action will be executed
  • How to associate the MenuItem with your action?

Your action
MenuItem
GUI framework
117
By class inheritance
  • MenuItem is an abstract base class that has an
    Execute()
  • Subclass implements Execute()
  • Simple, static binding

Abstract framework
MenuItem Execute()
Menu
MyMenuItem Execute()
Action()
118
By object delegation
Abstract framework
lthas-agt
Command
MenuItem Command c Clicked()
Menu
c-gtExecute()
CommandA Execute()
CommandB Execute()
Action1()
Action2()
119
Command object
  • Put a Command object inside a MenuItem object
  • aMenuItem.StoreCommand(Command c)
  • If MenuItem is clicked, c.Execute()is called
  • A difference between inheritance and delegation
  • Inheritance binded MenuItem with the action
  • Delegation decouples the two
  • The decoupling leads to a better reuse of the
    Command object (it can be used by more than one
    MenuItem )

120
How to support Undo /Redo ?
  • Each command object supports Execute() and
    UnExecute()
  • Clone a command object
  • Put the cloned object in a command history list
  • Redo gt clonedObject.UnExecute()

past commands
present
121
Command
  • Intent
  • Encapsulate a request as an object
  • Applications
  • Each MenuItem has a command object
  • e.g. new MenuItem(new IEG3080())
  • The .NETs delegate is an example of command

122
Problem
  • To check whether a student can register to a
    course
  • need to check the course, department, faculty,
    and university constraints
  • Example of constraints
  • credit exceeded, pre-requisites not met
  • Problem
  • Which object is responsible in doing the checking?

123
Chain of Responsibility
  • A simple solution
  • Pass the request along a chain of responsibility
  • Each object on the chain shares a common
    interface
  • It is like getting a form signed but you dont
    know who should sign it
  • So pass the form around until someone could
    handle it

124
Chain of Responsibility
  • Often applied in conjunction with Composite (i.e.
    tree structure)

client aHandler
IEHandler successor
ErgHandler successor
UniHandler successor
CSHandler successor
SciHandler successor
125
Chain of Responsibility
Handler Request()
client
successor
ConcreteHanlder1 Request()
ConcreteHanlder1 Request()
126
Chain of Responsibility
  • Intent
  • More than one object may handle a request, and
    the handler is not known
  • You want to issue a request to one of several
    objects without specifying the receiver
    explicitly
  • The structure is similar to a composite pattern
  • But composite pattern is focused on the structure
    of the objects
  • Chain of Responsibility is focused on the
    behavior of the objects

127
Problem multicast relationship
  • How to define a one-to-many dependency between
    objects so that when one object changes state,
    all its dependents are notified and updated
    automatically
  • e.g.

Central timer
Central Timer changes state Notify all other
clocks
1000am
200am
1000pm
HK time
London time
New York time
128
Observer Pattern
  • Key abstraction
  • Subject (e.g. central timer)
  • Observers (e.g. different clock)
  • Whenever the Subject changes its state, it
    notifies (Update()) all the Observers
  • Each Observer responds by getting the up-to-date
    information (GetState()) from the Subject
  • A new Observer can attach itself to the container
    of the Subject

129
Observer Pattern

1
Observer Update(subject)
Subject Attach(Observer) Detach(Observer) Notify()
observers
Foreach o in observers o.Update(this)
ConcreteObserver Update(subject)
ConcreteSubject GetState() . . .
observerState subject.GetState()
130
The multicast protocol
  • Subject has a list of Observers
  • An Observer uses Attach() and Detach() to add
    itself to Subjects list
  • Subject uses Update() to send notification to
    Observers
  • Pass itself to Observers as parameters
  • Observers use the passed Subject to get the new
    state information

131
GUI problem
  • User uses a mouse to click a button on the screen
  • Window manage detects the mouse click event
  • But how could the manager notify the button
    handler?

Window manager
?
MyButtonHandler Update()
Mouse click
Button
132
Class inheritance
  • Used by early version of MFC and Java (ver 1.0)

Window manager
Mouse click
Button Update()
MyButtonHandler Update()
133
Class inheritance
  • User clicks Button , the manager uses the current
    mouse position to locate Button
  • Manager calls Button.Update()
  • MyButtonHandler inherits the Button interface,
    MyButtonHandler.Update() is called
  • Limitation
  • Do not support multicast
  • Static binding, relationship is fixed at compile
    time, cannot attach or detach at run time

134
Object delegation
  • Used by current version of Java (the name
    Listener is used instead of Observer)
  • Advantages
  • Support multicast and dynamic binding (so that
    user can attach and detach observer at run time)

Window manager
Mouse click
Button Update() Listener list
Observer Update()
MyButtonHanlder Update()
135
Further improvement on the Observer pattern
  • Problem with Observer
  • Every event handler must inherit the Observer
    base class (which provides the Update()
    interface)
  • The Subject passes itself as argument to the
    Observer
  • How to specify the type of the Subject flexibly?
  • Delegate
  • An improved version of Observer
  • Use a Command object to encapsulate a pointer to
    the handler, eliminate Update() and the base
    class Observer

136
Callback by delegation (in L3 notes)
  • class MyWindow Form
  • static void Main()
  • Application.Run(new MyWindow())
  • public MyWindow()
  • this.MouseUp new EventHandler(this.Handler())
  • //MouseUp is a container
  • private void Handler(object sender,System.EventAr
    gs e)
  • Console.WriteLine(call from 0,sender.ToStrin
    g())

Command object
function pointer
Handler function
137
C delegate
  • User can also define a delegate with signature
  • More flexible, can pass type-safe information
  • public delegate void MyHandler(Student s)
  • Delegate Command Observer pattern

Window manager
C delegate object
Button Update() Listener list
Command
MyHandler Handler()
Command has a pointer to Handler()
138
Mediator
  • Problem
  • OO encourages distribution of responsibility, but
    this frequently leads to many connections between
    objects
  • The system is difficult to change because each
    object depends on many other objects

139
Mediator
  • Solution
  • Promotes loose coupling between objects via a
    central mediator

mediator
140
Mediator
  • Intent
  • Define an object that encapsulates how a set of
    objects interact
  • Mediator promotes loose coupling by keeping
    objects from referring to each other explicitly,
    and it lets you vary their interaction
    independently
  • Replace many-to-many interactions with
    one-to-many interactions
  • If an object is changed, only need to change the
    Mediator, but not the rest of the objects

141
Example dialog box
  • A dialog box has a number of widgets
  • Buttons, menus, and entry fields

142
Dependencies between widgets
  • Select an option in one widget causes changes in
    other widgets

143
  • Without mediator
  • If a widget is changed, need to notify other
    widgets
  • Creates dependency between widgets, tight
    coupling, makes future change difficult
  • With mediator
  • If a widget is changed, only need to notify the
    Mediator
  • Loose coupling, localized change
  • The Mediator centralizes control, to change the
    behavior only requires subclassing the Mediator

144
Mediator
145
How to test your code
  • A common generic pattern in testing
  • Set up the environment
  • Do some work
  • Tear down
  • TestCase()
  • SetUp()
  • while ( HasMore() )
  • Run()
  • TearDown()

146
Template Method
  • We have a fixed sequence of steps which are
    invariant, though the implementation of each step
    may change
  • We may carry out different testing, but the
    sequence remains the same
  • Template pattern encapsulates the sequence of
    business logic

147
Template Method
  • Base class defines the template of an algorithm,
    deferring the implementation to subclasses
  • Subclasses redefine certain steps of an algorithm
    without changing the algorithms structure

TestCase() SetUp() . . .
SetUp() . . .
148
Note
  • The template method TestCase() is non-virtual
  • Cannot be overrided by the subclass
  • So that the fixed sequence cannot be changed
  • Methods inside the template are protected
  • Intended to be overrided by the subclasses, but
    are not opened to public

149
Template Method
  • We have seen it before in creating a maze
  • Maze MazeGame.CreateMaze()
  • Maze aMaze makeMaze()
  • Room r1 makeRoom(1)
  • Room r2 makeRoom(2)
  • Door theDoor makeDoor(r1, r2)
  • aMaze.addRoom(r1)
  • aMaze.addRoom(r2)
  • . . .

A template of creating a maze
150
TCP (transmission control protocol) implementation
  • Problem
  • How to implement TCP?
  • TCP is complex !!
  • A connection can be in one of the many states
  • e.g. Listen, Established, SynSent
  • A connection may receive different requests
  • e.g. active open, close, acknowledge
  • Different state responds to the request
    differently

151
TCP state diagram
152
State
  • Listen, Established, Closed is-a kind of State

TCPState
SynSent
Established
Closed
153
State
  • Each TCPConnection has-a State

TCPConnection TCPState _state
TCPState
SynSent
Established
Closed
154
State
  • TCPConnection may receive many requests
  • e.g. connect, close, acknowledge

TCPConnection Connect() Close() Acknowledge()
TCPState _state
TCPState
SynSent
Established
Closed
155
Should TCPConnection handle the requests?
  • No, requests are state-dependent
  • Delegate the requests to the TCPState objects

TCPConnection Connect() . . . TCPState _state
TCPState Connect() . . .
SynSent Connect() . . .
Closed Connect() . . .
156
How to handle a request?
  • TCPConnection receives a connect request
  • TCPConnection object delegates the request to
    _state (the current TCPState object)
  • No ugly if-then-else block

157
How to handle a request?
  • class TCPConnection
  • private TCPState _state //current state
  • void Connect()
  • _state.Connect(this) //delegate
  • public void ChangeState(TCPState nextState)
  • _state nextState

158
To change the state of TCPConnection
  • The concrete object TCPState does the work, then
    use ChangeState() to change _state in
    TCPConnection to next state
  • class TCPClosed TCPState
  • void ActiveOpen(TCPConnection t)
  • //. . . send SYN
  • t.ChangeState(TCPSynSent.Instance)

Static property returning a Singleton of
TCPSynSent
159
State
  • For each concrete TCPState, only implement the
    functions that is meaningful
  • Meaningless requests can be ignored
  • Base class TCPState provides the dummy default
  • A do-nothing dummy default
  • public override void TCPState.Connect(TCPConnectio
    n t)

160
Singleton
  • None of the TCPState subclass has local state
    variables !
  • If the objects are stateless (have no memory)
  • Only need one object for each TCPState is enough
  • Singleton
  • Singleton object can be accessed directly

161
Singleton
Singleton, shared by all connections
TCPListen
TCPClosed
. . .
socket
TCPConnection
TCPState
162
Problem
  • How to encapsulate an algorithm so that your
    software can select between different algorithms
    flexibly?
  • e.g.
  • In word processing, choose between the different
    output formatter (pdf, postscript, rtf)
  • In action game, fighters can have different
    algorithm for different fighting level

163
  • Solution by subclassing
  • But subclassing makes it difficult for an object
    to change the algorithm at run time
  • The algorithm is statically binded to the
    concrete object

Base Class void Algo()
Derived Class A void Algo()
Derived Class B void Algo()
164
Strategy
  • Object delegation
  • the base class object is free to change the
    strategy object at run time

Strategy void Algo()
Base Strategy _s void Algo() _s-gtAlgo()
Derived class A void Algo()
Derived class B void Algo()
165
State and Strategy
  • Same class diagram, same pattern of code !
  • Differed by their intent and dynamics
  • States intent
  • Allow an object to alter its behavior when its
    internal state changes
  • Strategys intent
  • Define a family of algorithm, encapsulate each
    one, and make them interchangeable

166
Problem
  • How to add new functionality to a system?
  • e.g to add a print option to the registration
    system
  • Solution
  • Add Print() to the base class

Node Search() Print()
Course Search() Print() . . .
NodeList Search() Print() . . .
167
Problem
  • Modify the base class, violate the open-close
    principle!
  • Solution
  • Visitor Pattern
  • Visitor lets you define a new operation without
    changing the classes of the elements on which it
    operates

168
How it works
  • Accept() is a general-purpose method that can
    accept a Visitor object

Node Accept(Visitor v)
NodeList Accept(Visitor v) Node _list
Course Accept(Visitor v)
169
Visitor Pattern
  • A node accepts a visitor object
  • Node.Accept(Visitor v)
  • Node.Accept() immediately returns the call to
    Visitor and pass itself as the argument
  • v.Visit(this) //thisthe current node
  • Visitor.Visit(Node n) receives the node and does
    something about it
  • e.g. print the node, search the node

170
Code example
  • If the concrete node is a Course object
  • Course.Accept(Visitor v)
  • v.Visit(this) //callback
  • If the concrete node is a NodeList object
  • NodeList.Accept(Visitor v)
  • v.Visit(this) //process the list
  • foreach (Node n in _list)
  • n.Accept(v) //call each node in list

171
Visitor Visit(Node n)
PrintVisitor Visit(Node n) //doSomething
SearchVisitor Visit(Node n) //doSomething
Node Accept(Visitor v)
client
Course
NodeList
172
Note
  • Node usually has a tree (composite) structure
  • The visitor object transverses all nodes in the
    tree
  • Each node callbacks to the visitor visitor
    provides the new functionality
  • To add new functionality
  • simply add a new subclass of visitor,
  • no need to modify the object structure (Node)

173
Visitor Pattern
  • Refinement
  • Both Course and NodeList make a callback to the
    same visitor(Node n) method
  • Sometime we would like to treat callback from
    Course and NodeList differently,
  • e.g. PrintCourseName visitor
  • If callback from a Cours
Write a Comment
User Comments (0)
About PowerShow.com