Upload
camilla-york
View
222
Download
1
Tags:
Embed Size (px)
Citation preview
OO Methodology
Elaboration Iteration 2
- Design Patterns -
2
Table of Contents
• Iteration 1– Use-Case Model
– Process Sale Use Case
– Domain Model
– Design Model
• Iteration 2 Requirements
• GRASP: More Patterns for Assigning Responsibilities– Polymorphism
– Pure Fabrication
– Indirection
– Protected Variations
• Designing Use-Case Realizations with GoF Design Patterns
– Adapter
– Factory
– Strategy
– Composite
– Facade
– Observer
3
Iteration 2 Requirements
• Support for variations in third-party external services.
• Complex pricing rules
• Pluggable business rules
• A design to refresh a GUI window when the sale total changes
4
Refinements of Analysis-oriented Artifacts
• Use-case Model : Use Cases
• Use-case Model : SSDs– new system operations
– remotely communicating with external systems
• Domain Model
• Use-case Model : Operation Contracts
makeCreditPayment(credNum,expiryDate) reply :=
requestApproval(request)postReceivable( receivable
)
«actor»:CreditAuthorization
Service
«actor»:Accounts
enterItem(itemID,quantity)
:NextGenPOSSystem
: Cashier
endSale()
Process SalePay by Credit Scenario
description,total
total withtaxes
* [more items]
makeNewSale()
«actor»:TaxCalculator
taxLineItems :=getTaxes( sale
)
postSale( sale)
5
More GRASP Patterns
• Polymorphism
• Indirection
• Pure Fabrication
• Protected Variations
6
Design Patterns
• What is Design Pattern– reuses design
– describes a particular recurring design problem that arises in specific design contexts, and presents a well-proven generic scheme for its solution
• Four essential elements– pattern name
– problem
– solution
– consequences
• Gang of Four[GOF95]– creational patterns – 5 patterns
• concern the process of object creation.
– structural patterns – 7 patterns• deal with the composition of classes or objects.
– behavioral patterns – 11 patterns• characterize the ways in which classes or objects interact and
distribute responsibility.
7
Design Pattern Space(GoF)
• Scope– Class patterns deal with relationships between classes and
their subclasses• established through inheritance• they are static—fixed at compile-time
– Object patterns deal with object relationships• can be changed at run-time and are more dynamic.• almost all patterns use inheritance to some extent.
Purpose
Creational Structural Behavioral
Scope
Class Factory Method Adapter Interpreter
Template
Method
Object Abstract Factory
Builder
Prototype
Singleton
Adapter
Bridge
Composite
Decorator
Facade
Flyweight
Proxy
Chain of
Responsibility
Command
Iterator
Mediator
Memento
Observer
State
Strategy
Visitor
8
Describing Design Patterns(GoF)
• Pattern Name and Classification
• Intent
• Also Known As
• Motivation
• Applicability
• Structure
• Participants
• Collaborations
• Consequences
• Implementation
• Sample Code
• Known Uses
• Related Patterns
9
How Design Patterns Solve Design Problems
– Finding Appropriate Objects• most objects come from the analysis model• abstraction • pure fabrication
– Determining Object Granularity• describe specific ways of decomposing an object into smaller
objects
– Specifying Object Interfaces• subtype• dynamic binding• polymorphism
– Specifying Object Implementations• class inheritance• cf. interface inheritance
– Putting Reuse Mechanisms to Work• Inheritance• Composition• Delegation
– Relating Run-Time and Compile-Time Structures– Designing for Change
• indirect creation of objects• avoiding hard-coded requests• limiting platform dependencies• hiding object implementations• avoiding algorithmic dependencies• loose coupling • using composition and delegation over inheritance• etc.
10
How to Use a Design Pattern
• Issues– Is there a pattern that addresses a similar problem
– Does the pattern trigger an alternative solution that may be more acceptable
– Is there a simple solution?
– Is the context of the pattern consistent with that of the problem
– Are the consequences of using the pattern acceptable
– Are constraints imposed by the software environment that would conflict with the use of the pattern
• GoF suggest a procedure1. Read the pattern once through for an overview.
2. Go back and study the Structure, Participants, and Collaborations sections.
3. Look at the Sample Code section to see a concrete example of the pattern in code.
4. Choose names for pattern participants that are meaningful in the application context.
5. Define the classes.
6. Define application-specific names for operations in the pattern
7. Implement the operations to carry out the responsibilities and collaborations in the pattern.
11
Adapter Pattern
• The NextGen POS – needs to support several kinds of external third-party
services, including tax calculators, credit authorization services
• Adapter pattern– Context/Problem
• How to resolve incompatible interfaces, or provide a stable interface to similar components with different interfaces?
– Solution• Convert the original interface of a component into another
interface, through an intermediate adapter object, that adapts the varying external interfaces
12
Adapter Pattern
• NextGen POS system needs to support several kinds of external third-party services, including tax calculators, credit authorization services, inventory systems etc.
TaxMasterAdapter
getTaxes( Sale ) : List of TaxLineItems
GoodAsGoldTaxProAdapter
getTaxes( Sale ) : List of TaxLineItems
<<interface>>ITaxCalculatorAdapter
getTaxes( Sale ) : List of TaxLineItems
Adapters use interfaces andpolymorphism to add a level ofindirection to varying APIs in othercomponents.
SAPAccountingAdapter
postReceivable( CreditPayment )postSale( Sale )...
GreatNorthernAccountingAdapter
postReceivable( CreditPayment )postSale( Sale )...
<<interface>>IAccountingAdapter
postReceivable( CreditPayment )postSale( Sale )...
<<interface>>IInventoryAdapter
...
<<interface>>ICreditAuthorizationService
Adapter
requestApproval(CreditPayment,TerminalID, MerchantID)...
13
Adapter Pattern
• Using an Adapter
• Adapter pattern offers Protected Variations from changing external interfaces or third-party packages through the use of an Indirection object that applies interfaces and Polymorphism
:Register : SAPAccountingAdapter
postSale( sale )
makePayment()
the Adapter adapts tointerfaces in othercomponents
«system»: SAP
SOAP overHTTP
xxx
...
IAccountingAdapter
UML notation to indicate somethingimplements a particular interface
14
Adapter Pattern
• Class Adapter– uses multiple inheritance to adapt one interface to another
• Object Adapter– uses object composition
15
Adapter Pattern
• Example (Drawing Editor)– TextView interface does not match the domain-specific
interface an application requires
16
Adapter Pattern
• Sample Code(Drawing Editor)class Shape {
public: Shape(); virtual void BoundingBox( Point& bottomLeft,
Point& topRight ) const; virtual Manipulator* CreateManipulator() const;
}; class TextView {
public: TextView(); void GetOrigin(Coord& x, Coord& y) const; void GetExtent(Coord& width, Coord& height)
const; virtual bool IsEmpty() const;
}; class TextShape : public Shape, private TextView { // class
adaterpublic:
TextShape(); virtual void BoundingBox( Point& bottomLeft,
Point& topRight ) const; virtual bool IsEmpty() const; virtual Manipulator* CreateManipulator() const;
}; void TextShape::BoundingBox ( Point& bottomLeft, Point&
topRight ) const { Coord bottom, left, width, height;
GetOrigin(bottom, left); GetExtent(width, height); bottomLeft = Point(bottom, left); topRight = Point(bottom + height, left + width);
}
17
Adapter Pattern
• Sample Code(Drawing Editor)class TextShape : public Shape { // object
adaterpublic:
TextShape(TextView*); virtual void BoundingBox( Point&
bottomLeft, Point& topRight ) const; virtual bool IsEmpty() const; virtual Manipulator*
CreateManipulator() const; private:
TextView* _text; };
TextShape::TextShape (TextView* t) { _text = t; } void TextShape::BoundingBox ( Point& bottomLeft,
Point& topRight ) const { Coord bottom, left, width, height; _text->GetOrigin(bottom, left); _text->GetExtent(width, height); bottomLeft = Point(bottom, left); topRight = Point(bottom + height, left + width);
}
18
Factory Pattern
• NextGen POS– who creates the adapters?
– how to determine which class of adapter to create?
– Choosing a domain object to create the adapters does not support the goal of a separation of concerns and lowers its cohesion
• Factory (Concrete Factory)– Context
• Who should be responsible for creating objects when there are special considerations, such as complex creation logic, a desire to separate to creation responsibilities for better cohesion, etc.?
– Solution• Create a Pure Fabrication object called a Factory that handles
the creation
– Advantages• Separate the responsibility of complex creation into cohesive
helper objects
• Hide potentially complex creation logic
• Allow introduction of performance-enhancing memory management strategies such as object caching or recycling
• GoF– Abstract Factory
– Factory Method
19
Factory Pattern
• Factory
• Using data-driven design (Protected Variation)
ServicesFactory
accountingAdapter : IAccountingAdapterinventoryAdapter : IInventoryAdaptertaxCalculatorAdapter : ITaxCalculatorAdapter
getAccountingAdapter() : IAccountingAdaptergetInventoryAdapter() : IInventoryAdaptergetTaxCalculatorAdapter() : ITaxCalculatorAdapter...
note that the factory methodsreturn objects typed to aninterface rather than a class, sothat the factory can return anyimplementation of the interface
{ if ( taxCalculatorAdapter == null ) { // a reflective or data-driven approach to finding the right class: read it from an // external property
String className = System.getProperty( "taxcalculator.class.name" ); taxCalculatorAdapter = (ITaxCalculatorAdapter) Class.forName( className ).newInstance();
} return taxCalculatorAdapter;}
20
Singleton Pattern
• NextGen POS– who creates the factory itself, and how is it accessed?
– only one instance of the factory is needed
– this factory may need to be called from various places in the code
• Singleton– Context
• Exactly one instance of a class is allowed.
• Objects need a global and single point of access
– Solution• Define a static method of the class that returns the singleton
21
Singleton Pattern
• Factory for external services
1ServicesFactory
instance : ServicesFactory
accountingAdapter : IAccountingAdapterinventoryAdapter : IInventoryAdaptertaxCalculatorAdapter : ITaxCalculatorAdapter
getInstance() : ServicesFactory
getAccountingAdapter() : IAccountingAdaptergetInventoryAdapter() : IInventoryAdaptergetTaxCalculatorAdapter() : ITaxCalculatorAdapter...
singletonstatic attribute
singletonstaticmethod
{// static methodpublic static synchronized ServicesFactory getInstance(){if ( instance == null ) instance := new ServicesFactory()return instance}}
UML notation: in aclass box, anunderlined attribute ormethod indicates astatic (class level)member, rather thanan instance member
UML notation: this '1' can optionally be used toindicate that only one instance will be created (asingleton)
22
Singleton Pattern
• Visibility to the singleton (global)public class Register
{
public void initialize() {
...
accountingAdapter = ServiceFactory.getInstance().
getAccountingAdapter();
...
}
...
}
• UML Shorthand
:Register<<singleton>>
:ServicesFactory
aa := getAccountingAdapter()initialize()
...
a UML stereotype can indicate thatvisibility to this instance wasachieved via the Singleton pattern
23
Adapter, Factory, Singleton
:Register accountingAdapter:SAPAccountingAdapter
postSale( sale )
makePayment()
«system»: SAP
SOAP overHTTP
xxx
IAccountingAdapter
:Register
<<singleton>>:ServicesFactory
accountingAdapter := getAccountingAdapter()
:Store
create()create()
[ instance == null ]create() : SAPAccounting
Adapter
IAccountingAdapter
: Paymentcreate(cashTendered)
24
Abstract Factory
• Context– when a system should be configured with one of multiple
families of products
– a family of related product objects is designed to be used together
– how can these families of products be created
• Solution– provide an interface for creating families of related or
dependent objects without specifying their concrete classes
• Structure
25
Abstract Factory
• Example : User Interface Toolkit
• Consequences– It isolates concrete classes
– It makes exchanging product families easy.
– It promotes consistency among products
– Supporting new kinds of products is difficult
26
Abstract Factory
• Sample : Maze Game
class MapSite { public: virtual void Enter() = 0; };
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; };
27
Abstract Factory
• Sample : Maze Gameclass 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* _room1; Room* _room2; bool _isOpen; }; class Maze { public: Maze(); void AddRoom(Room*); Room* RoomNo(int) const; private: // ... };
28
Abstract Factory
• Sample : Maze Game
– In another class MazeGame, a Maze is created
Maze* MazeGame::CreateMaze () { Maze* aMaze = new Maze; Room* r1 = new Room(1);
Room* r2 = new Room(2); Door* theDoor = new Door(r1, r2); aMaze->AddRoom(r1); aMaze->AddRoom(r2); r1->SetSide(North, new Wall); r1->SetSide(East, theDoor); r1->SetSide(South, new Wall); r1->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;
}
– hard-coded– how can you change CreateMaze easily so that it
creates another family of components of maze for example, enchanted maze
29
Abstract Factory
• Alternative: Abstract Factory
MazeFactory
EnchantedMazeFactory
BombedMazeFactory
Maze
EnchantedMaze
BombedMaze
Room
EnchantedRoom
BombedRoom
Wall
EnchantedWall
BombedWall
MazeGame
30
Abstract Factory
• Alternative: Abstract Factory– MazeFactory classclass MazeFactory {
public: MazeFactory(); virtual Maze* MakeMaze() const { return new Maze; } virtual Wall* MakeWall() const { return new Wall; } virtual Room* MakeRoom(int n) const
{ return new Room(n); } virtual Door* MakeDoor(Room* r1, Room* r2) const { return new Door(r1, r2); }
};
– creating a maze using an abstract factoryMaze* MazeGame::CreateMaze (MazeFactory&
factory) { Maze* aMaze = factory.MakeMaze();
Room* r1 = factory.MakeRoom(1); Room* r2 = factory.MakeRoom(2); Door* aDoor = factory.MakeDoor(r1, r2); aMaze->AddRoom(r1); aMaze->AddRoom(r2); r1->SetSide(North, factory.MakeWall()); r1->SetSide(East, aDoor); r1->SetSide(South, factory.MakeWall());
....r2->SetSide(West, aDoor); return aMaze;
}
31
Abstract Factory
• Alternative: Abstract Factory
– enchanted maze factory
class EnchantedMazeFactory : public MazeFactory { public:
EnchantedMazeFactory(); virtual Room* MakeRoom(int n) const { return new EnchantedRoom(n,
CastSpell()); } virtual Door* MakeDoor(Room* r1,
Room* r2) const { return new DoorNeedingSpell(r1, r2); }
protected: Spell* CastSpell() const;
};
– create a bombed maze
MazeGame game; BombedMazeFactory factory; game.CreateMaze(factory);
32
Factory Method
• Intent– Define an interface for creating an object, but let subclasses
decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
• Motivation– Consider a framework for applications that can present
multiple documents to the user.
33
Factory Method
• Applicability– a class can't anticipate the class of objects it must create.
– a class wants its subclasses to specify the objects it creates.
• Structure
• Consequences– eliminates the need to bind application-specific classes
– provides a hooks for subclasses
34
Factory Method
• Sample Codeclass MazeGame { public:
Maze* CreateMaze(); // factory methods: virtual Maze* MakeMaze() const { return new Maze; } virtual Room* MakeRoom(int n) const
{ return new Room(n); } virtual Wall* MakeWall() const { return new Wall; } virtual Door* MakeDoor(Room* r1, Room* r2) const { return new Door(r1, r2); }
}; Maze* MazeGame::CreateMaze () {
Maze* aMaze = MakeMaze(); Room* r1 = MakeRoom(1); // using factory methodsRoom* r2 = MakeRoom(2); Door* theDoor = MakeDoor(r1, r2); aMaze->AddRoom(r1); aMaze->AddRoom(r2); r1->SetSide(North, MakeWall()); r1->SetSide(East, theDoor); r1->SetSide(South, MakeWall());
....return aMaze; }
35
Factory Method
• Sample Code
– EnchantedMazeGame subclass refines factory methods
class EnchantedMazeGame : public MazeGame { public:
EnchantedMazeGame(); virtual Room* MakeRoom(int n) const
{ return new EnchantedRoom(n, CastSpell()); } virtual Door* MakeDoor(Room* r1, Room* r2) const { return new DoorNeedingSpell(r1, r2); }
protected: Spell* CastSpell() const;
};
– creating a maze
EnchantedMazeGame game;game.CreateMaze();