Advanced Object-oriented Design Patterns Creational Design Patterns.
Creational Design Patterns · Creational patterns • Because the creational patterns are closely...
Transcript of Creational Design Patterns · Creational patterns • Because the creational patterns are closely...
Creational Design Patterns
• Creational Design Patterns
• Structural Design Patterns
• Behavioral Design Patterns
GoF Design Pattern Categories
2
Purpose
Creational Structural Behavioral
Scope Class Factory Method Adapter Interpreter
Template Method
Object Abstract Factory
Builder
Prototype
Singleton
Adapter
Bridge
Composite
Decorator
Facade
Proxy
Flyweight
Chain of Responsibility
Command
Iterator
Mediator
Memento
Observer
State
Strategy
Visitor
Creational Design Patterns
● Abstracts instantiation process
●Makes system independent of how its objects are
o created
o composed
o represented
● Encapsulates knowledge about which concrete classes the
system uses
● Hides how instances of these classes are created and put
together
3
Creational Design Patterns
●A class creational pattern uses inheritance to vary the
class that's instantiated, whereas an object creational
pattern will delegate instantiation to another object.
4
Creational Design Patterns
●Creational patterns become important as systems evolve to
depend more on object composition than class inheritance.
●Emphasis shifts from hardcoding fixed sets of behaviors
towards a smaller set of composable fundamental behaviors
that can be composed into any number of more complex
ones.
●Thus creating objects with particular behaviors requires
more than simply instantiating a class.5
Creational Design Patterns
●Recurring themes:
oEncapsulate knowledge about which concrete classes
the system uses (so we can change them easily later)
oHide how instances of these classes are created and put
together (so we can change it easily later)
6
Benefits of creational patterns● Creational patterns let you program to an interface defined by an
abstract class
● That lets you configure a system with “product” objects that vary
widely in structure and functionality
● Example: GUI systems
o InterViews GUI class library
oMultiple look-and-feels
oAbstract Factories for different screen components
7
Benefits of creational patterns
●Generic instantiation – Objects are instantiated without having to
identify a specific class type in client code (Abstract Factory, Factory)
● Simplicity – Make instantiation easier: callers do not have to write
long complex code to instantiate and set up an object (Builder,
Prototype pattern)
● Creation constraints – Creational patterns can put bounds on who can
create objects, how they are created, and when they are created
8
Creational patterns
• Because the creational patterns are closely related, we'll study all five of them together to highlight their similarities and differences.
• We'll also use a common example building a maze for a computer game to illustrate their implementations.
• The maze and the game will vary slightly from pattern to pattern.
• We'll ignore many details of what can be in a maze and whether a maze game has a single or multiple players.
• Instead, we'll just focus o n how mazes get created.
• We define a maze as a set of rooms.
• A room knows its neighbors; possible neighbors are another room, a wall, or a door to another room.
9
Creational patterns
• The classes Room, Door, and Wall define the components of themaze used in all our examples.
• We define only the parts of these classes that are important forcreating a maze.
• We'll ignore players, operations for displaying and wandering aroundin a maze, and other important functionality that isn't relevant tobuilding the maze.
10
Creational patterns
11
Creational patterns
�The class MapSite is the common abstract class for all the components of a maze
class MapSite {
public:
virtual void Enter()=0
}
•
12
Creational patterns
�Room is the concrete subclass of MapSite that defines the key relationships between components in the maze.
�It maintains references to other MapSite objects and stores a room number. The number will identify rooms in the maze.
• Enter provides a simple basis for more sophisticated game operations.
• For example, if you are in a room and say "GoEast," the game can simply determine which MapSite is immediately to the east and then call Enter on it.
13
Creational patterns
class Room : public MapSite {
public:
Room(int roomNo);
MapSite* GetSide(Direction) const;
void SetSide(Direction, MapSite*);
virtual void Enter();
private:
MapSite* _sides[4];
int _roomNumber;
};
14
Creational patternsclass Wall : public MapSite {
public:
Wall();
virtual void Enter();}
---------------------------------
class Door : public MapSite {
public:
Door(Room* = 0, Room* = 0);
virtual void Enter();
Room* OtherSideFrom(Room*);
private: Room* _rooml;
Room* _room2;
bool _isOpen;}
15
Creational patterns�We need to know about more than just the parts of a maze.
�We'll also define a Maze class to represent a collection of rooms.
�Maze can also find a particular room given a room number using its RoomNooperation.
class Maze {
public:
Maze();
void AddRoom(Room* ) ;
Room* RoomNo(int) const;
private:
// . . .
};
16
Creational patterns
• Another class is MazeGame, which creates the maze. Onestraightforward way to create a maze is with a series of operationsthat add components to a maze and then interconnect them.
• For example, the following member function will create a mazeconsisting of two rooms with a door between them:
17
Creational patternsMaze* MazeGame::CreateMaze () {
Maze* aMaze = new Maze;
Room* rl = new Room(l);
Room* r2 = new Ro om (2);
Door* theDoor = new Door(rl, r2);
aMaze->AddRoom(rl);
aMaze->AddRoom(r2);
rl->SetSide(North, new Wall);
rl->SetSide(East, theDoor);
rl->SetSide(South, new Wall);
rl->SetSide(West, new Wall);
r2->SetSide(North, new Wall);
r2->SetSide(East, new Wall);
r2->SetSide(South, new Wall);
r2->SetSide(West, theDoor);
return aMaze;
18
Creational patterns
• The real problem with this member function isn't its size but itsinflexibility.
• It hard-codes the maze layout.
• Changing the layout means changing this member function, either byoverriding it—which means reimplementing the whole thing—or bychanging parts of it—which is error-pronaend doesn't promote reuse.
• The creational patterns show how to make this design more flexible,not necessarily smaller.
19
Creational patterns
�The creational patterns provide different ways to remove explicitreferences to concrete classes from code that needs to instantiatethem:
• • If CreateMaze calls virtual functions instead of constructor calls tocreate the rooms, walls, and doors it requires, then you can changethe classes that get instantiated by making a subclass of MazeGameand redefining those virtual functions.
This approach is an example of the Factory Method pattern.
• • If CreateMaze is passed an object as a parameter to use to createrooms, walls, and doors, then you can change the classes of rooms,walls, and doors by passing a different parameter.
This is an example of the Abstract Factory pattern.
• •
20
Creational patterns
• • If CreateMazeis passed an object that can create a new maze initsentirety using operations for adding rooms, doors, and walls to themaze it builds, then you can use inheritance to change parts of themaze or the way the maze is built.
• This is an example of the Builder pattern.
• • If CreateMaze is parameterized by various prototypical room, door,and wall objects, which it then copies and adds to the maze, then youcan change the maze's composition by replacing these prototypicalobjects with different ones.
• This is an example of the Prototype pattern.
21
Abstract Factory (Object Creational)
22
Intent Provide an interface for creating families of related or dependent
objects without specifying their concrete classes
Pattern summary Capture family creation in a class containing a factory method for
each class in the family
Also Known as Kit
Abstract Factory - Motivation
23
1) Implement a user interface toolkit that supports multiple looks and
feel standards such as Motif, Windows 95 or the finder in MacOS.
How can you write a single user interface and make it portable across
the different look and feel standards for these window managers?
2) Implement a facility management system for an intelligent house
that supports different control systems such as Siemens’ Instabus,
Johnson & Control Metasys or Zumtobe’s proprietary standard.
How can you write a single control system that is independent from
the manufacturer?
Abstract Factory - Motivation
24
Different look-and-feels define different appearances and behaviors
for user interface "widgets" like scroll bars, windows, and buttons.
To be portable across look-and-feel standards, an application should
not hard-code its widgets for a particular look and feel.
Instantiating look-and feel specific classes of widgets throughout the
application makes it hard to change the look and feel later.
25
Abstract Factory
26
The Client remains blissfully unaware of the various concrete classes in this
example. Client code deals with the simpler, abstract, general case.
27
Abstract Factory applicability
28
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.
Abstract Factory 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 o f product object.
�ConcreteProduct (MotifWindow, MotifScrollBar)
�- defines a product object to be created by the corresponding concretefactory.
�- implements the AbstractProduct interface.
�Client
�- uses only interfaces declared by AbstractFactory and AbstractProduct
classes.
29
Abstract Factory Collaborations
�Normally a single instance of a Concrete Factory class is created at run-time.
�
�To create different product objects, clients should use a different concrete factory.
� Abstract Factory defers creation of product objects to itsConcrete Factory subclass.
30
Abstract Factory Consequences
31
●The Abstract Factory Pattern has the following benefits:
oIt isolates concrete classes from the client.
You use the Abstract Factory to control the classes of objects
the client creates.
Product names are isolated in the implementation of the
ConcreteFactory, clients use the instances through their
abstract interfaces.
Abstract Factory Consequences
32
o Exchanging product families is easy.
None of the client code breaks because the abstract interfaces
don’t change.
Because the abstract factory creates a complete family of
products, the whole product family changes when the concrete
factory is changed.
o It promotes consistency among products.
It is the concrete factory’s job to make sure that the right
products are used together.
Abstract Factory Consequences
33
oAdding new kinds of products to existing factory is difficult.
Adding a new product requires extending the abstract
interface which implies that all of its derived concrete
classes also must change.
Abstract Factory Implementation
34
● Concrete factories are often implemented as singletons.
● Creating the products
oConcrete factory usually use the factory method.
simple
new concrete factory is required for each product family
oalternately concrete factory can be implemented using prototype.
only one is needed for all families of products
product classes now have special requirements - they participate in
the creation
Abstract Factory Implementation
35
●Defining extensible factories by using create function with an
argument
oonly one virtual create function is needed for the AbstractFactory
interface
oall products created by a factory must have the same base class or
be able to be safely coerced to a given type
o it is difficult to implement subclass specific operations
Abstract Factory - Example
SomeApp Shape<<Interface>>
Square Circle
<<creates>>
36
We have a class named SomeApp that depends on the interface
Shape.
Shape uses instances of Shape solely through the Shape interface.
Problem: SomeApp also creates instances of Square and Circle and
thus has to depend on the concrete classes.
Abstract Factory - Example
Shape<<Interface>>
Square Circle
ShapeFactory Implementation
<<creates>>
SomeApp
ShapeFactory<<Interface>>
makeSquare()makeCircle()
37
Solution: ShapeFactory interface.
Know Uses
●Interviews
o used to generate “look and feel” for specific user interface objects
o uses the Kit suffix to denote AbstractFactory classes, e.g., WidgetKit and
DialogKit.
o also includes a layoutKit that generates different composite objects depending
on the needs of the current context
ET++
o another windowing library that uses the AbstractFactory to achieve portability
across different window systems (X Windows and SunView).
● COM – Microsoft’s Component Object Model technology
o Each COM component provides a concrete factory bound to the IClassFactory
interface and provides clients specific instances bound to the server’s product
interface.38
Related Patterns
●Factory Method -- a “virtual” constructor
●Prototype -- asks products to clone themselves
●Singleton -- allows creation of only a single instance
39
40
41
42
43
44
interface Isimple //product A
{
string GetName();
}
------------
interface Ismart product B
{
string GetName();
}
----------------
enum TypePhone
{ Samsung, Nokia, HTC }
45
class Galaxy : ISmart
{
public string GetName()
{ return "Galaxy"; }
}
-------------------------
class Lumia : ISmart
{
public string GetName()
{ return "Lumia"; }
}
--------------
class Titan : ISmart
{
public string GetName()
{ return "Titan"; }
}
46
class Primo : ISimple
{
public string GetName()
{ return "Primo"; }
}
-------------
class Asha : ISimple
{
public string GetName()
{ return "Asha"; }
}
-------
class Genie : ISimple
{
public string GetName()
{ return "Genie"; }
}
47
abstract class AbstractPhoneFactory
{
public virtual ISmart GetSmart() { return null; }
public virtual ISimple GetSimple() { return null; }
}------------
class SamsungFactory : AbstractPhoneFactory
{
public override ISimple GetSimple()
{ return new Primo(); }
public override ISmart GetSmart()
{ return new Galaxy(); }
} 48
class NokiaFactory : AbstractPhoneFactory
{
public override ISimple GetSimple()
{ return new Asha(); }
public override ISmart GetSmart()
{ return new Lumia(); }
}
----------------------------------------
class HTCFactory : AbstractPhoneFactory
{
public override ISimple GetSimple()
{ return new Genie(); }
public override ISmart GetSmart()
{ return new Titan(); }
}
49
class AbstractFactory
{
public static AbstractPhoneFactory CreateFactory(TypePhone TypeP)
{
AbstractPhoneFactory Aphone=null;
switch (TypeP)
{
case TypePhone.HTC: Aphone = new HTCFactory();
break;
case TypePhone.Nokia: Aphone= new NokiaFactory();
break;
case TypePhone.Samsung:Aphone=new SamsungFactory();
break;
}
return Aphone;
}
}50
private void button1_Click(object sender, EventArgs e)
{
SamsungFactory s =(SamsungFactory)
AbstractFactory.CreateFactory(TypePhone.Samsung);
ISmart ismart = s.GetSmart();
MessageBox.Show(ismart.GetName());
}
51