Design Patterns

advertisement
Design Patterns
Dennis Mancl
Alcatel-Lucent – Bell Labs
November 28, 2007
1
Design Patterns Outline
• What is a pattern?
– The Design Patterns Book
– One example pattern: Singleton
– Patterns versus Idioms
•
•
•
•
•
•
Wrapping with Facade objects
Remote access with Proxy
Observer
Analysis patterns
Architectural patterns
Enterprise Architecture patterns
2
What is a pattern?
• A pattern is a solution to a
problem in a context
• The problem and context
come from some domain
(software development,
project management, …)
– The problem and context
contain some “unresolved
forces” that need to be
addressed.
• The solution is a proposed
way to resolve the problem
Name: Information Expert
Problem: How to decide which
class or object to assign
responsibilities to?
Context: A responsibility usually
requires some information or data
for its fulfillment – information about
other objects, an object’s own state,
the world around an object, and so
on.
Solution: Assign a responsibility to
the class that has the information
needed to fulfill it.
(from Applying UML and Patterns, third edition,
Craig Larman)
3
What is a pattern?
• Patterns are used
to capture
knowledge and
experience – for
example, what to
think about when
making design
choices
• Not a cookbook
• Each pattern
might trigger
others
Name: Loose Interfaces
Problem: To avoid development bottlenecks, we
need to be able to limit the effect that one team’s work
will have on another.
Context: Interfaces need to be somewhat flexible if
the teams are working quickly. Requirements may be
changing rapidly, and it may be difficult to
communicate between geographically distributed
subteams.
Solution: Limit the number of explicit, static
interfaces. Define larger-grained interfaces that allow
developers to code against interfaces defined early,
but that do not overly constrain functionality. Consider
using the Hierarchy of Factories pattern.
(from Organizational Patterns of Agile Software Development, Coplien and
Harrison)
4
Patterns in non-software domains
• Name: ChocolateChipRatio
• Context: You are baking chocolate chip cookies in small batches for
family and friends
• Consider these patterns first: SugarRatio, FlourRatio, EggRatio
• Problem: Determine the optimum ratio of chocolate chips to cookie
dough
• Solution: Observe that most people consider chocolate to be the
best part of the chocolate chip cookie. Also observe that too much
chocolate may prevent the cookie from holding together, decreasing
its appeal. Since you are cooking in small batches, cost is not a
consideration. Therefore, use the maximum amount of chocolate
chips that results in a sturdy cookie.
• Consider next: WalnutRatio or CookingTime or FreezingMethod
(from Wikipedia: http://en.wikipedia.org/wiki/Pattern_language)
5
Software patterns
• The first “Object Oriented Design
Patterns” are found in the book
– Design Patterns by Erich Gamma,
Richard Helm, Ralph Johnson, and John
Vlissides (known as “Gang of 4” or “GOF”)
– 23 patterns: three categories (Creational,
Structural, Behavioral)
– Problems:
• control the construction of objects
• create organized collections of objects
• divide responsibilities among objects for
better encapsulation and easier
modification
– Examples in C++ and Smalltalk
– The patterns also apply to other
languages (Java, Visual Basic, Perl)
6
Singleton Pattern
• Name: Singleton
• Problem: We need to restrict the creation of new objects
for a particular class: only one instance.
• Context: Other objects in the design need a single point
of access to use the object.
• Solution: Define a “static member function” within the
class that returns a pointer (or reference) to the
Singleton object. The static member function will create
the object the first time it is called. All constructors are
made private to prevent other objects from being
created.
7
More about Singleton
• Simple version of Singleton (in C++, without multi-thread support):
MySingletonClass
– instance : MySingletonClass *
other attributes …
+ getInstance() : MySingletonClass *
– MySingletonClass()
other operations …
underline means
static data member
if (instance == 0) {
instance =
new MySingletonClass();
}
return instance;
• Access the Singleton like this: MySingletonClass::instance()
• Different implementations of the Singleton pattern for Java,
multithreaded support, allocation in special memory, and so on.
8
Patterns and Idioms
• What have we done? We have used a “design trick” that
solves a specific problem
• Some standard design tricks are called “idioms”
– they tend to be small, tricky, and language specific
– example: virtual destructors in C++
– example: anonymous inner classes in Java
• How are patterns different from idioms?
– Patterns are more about design
– Singleton is useful in Java, Smalltalk, Visual Basic, Perl, …
– different “realizations” of patterns in different languages
9
Patterns in the Design Patterns book
• 23 Design Patterns: three categories
Creational
Structural
Abstract
Factory
Adapter
Chain of
Responsibility
Observer
Builder
Bridge
Command
State
Interpreter
Strategy
Factory Method Composite
Behavioral
Prototype
Decorator
Iterator
Template
Method
Singleton
Facade
Mediator
Visitor
Flyweight
Memento
Proxy
10
Sources of information
• So, you want to learn how to use these design patterns
– to make your OO designs better
• Where to look to learn more:
– the book
– A Learning Guide to Design Patterns
(http://www.industriallogic.com/papers/learning.html)
– Pattern Stories Wiki (http://wiki.cs.uiuc.edu/PatternStories)
– http://c2.com/cgi/wiki?DesignPatterns
– other books:
•
•
•
•
Pattern-Oriented Software Architecture by Frank Buschmann et. al.
Design Patterns Java Workbook by Steven John Metsker
Refactoring to Patterns by Joshua Kerievsky
Design Patterns Explained by Alan Shalloway and James R. Trott
11
Why learn the Design Patterns?
• Your own designs will improve
– borrowing well-tested ideas
– pattern descriptions contain some analysis of tradeoffs
• You will be able to describe complex design ideas to
others
– assuming that they also know the same patterns
• You can use patterns to “refactor” existing code
– refactoring is improving the structure of existing code without
adding new functionality
– some techniques for transforming and adapting legacy code are
based on design patterns
12
Facade Pattern
• Problem: The application needs a simple interface to a
complex subsystem
– the subsystem might have been written by someone else
– you don’t want the entire development team to go back to the
subsystem documentation with lots of questions
• Context:
– it is important to control the dependencies between the application and
the complex subsystem – you want to reduce the effort to maintain the
system
• Solution: Define a single Facade class
– the Facade class has knowledge of the internal details of the
subsystem, but the Facade class provides a simple to use interface for
the application
– each Facade public function might call many subsystem operations
13
Facade diagram
• A Facade class wraps a bunch of operations on other classes (or a
bunch of legacy code operations) into a convenient package
application
application calls
some of the Facade
class operations
Facade class
scanner
pointers to other data
objects within a
subsystem
get_val1()
build_trans2()
do_trans3()
commit_trans4()
the Facade accesses
some of the internals
of a complex subsystem to
implement its operations
database
interface
parser
formatter
14
Planning a Facade
• Part of the OO design process: create a simplified
model of the classes in the overall system
– using CRC cards (informal technique using index cards, one
card per class)
– using UML Class Diagrams
• Look for a group of classes that collaborate closely
together: call them a “subsystem”
• Try to “put the subsystem behind a wall” – define a single
interface class that defines an API for the subsystem
15
Proxy example
• A Proxy object is a “stand-in” for an object that might be:
– located on another machine (example: CORBA objects, Java RMI)
– or it might be large and complicated, so you want to defer building it
– or it might require a special access method (to check the users’
permissions)
CORBA example
client application
Stub objects have full
public interface, but no data.
They just push a message
over to the server.
ORB (server)
CORBA
IDL stubs
IDL skeletons
Interface
Repository
Object
Implementations
network
requests
responses
Generated
by a tool
Developers
fill in details
16
Proxy pattern
• Problem: The application needs to operate on a distant
object
• Context: Need a placeholder for an object
– if the actual object is far away (on another computer or on a
disk), the placeholder should be in the local address space
• Solution: Define a Proxy class: this class will have the
same public interface as the real class, and when a
Proxy operation is called, the internals of a Proxy object
will arrange for the same function to be called on a real
object
– Proxy might send interprocess or intermachine messages
– Proxy might resurrect an object that has been written to disk
– Proxy might acquire special permissions to access a protected
real object
17
How to tell the difference?
• How can I tell which one I am using? Facade or Proxy?
– Both patterns are separating the implementation details from an
abstract interface
– But the intent is different for each pattern
• Facade: the application wants to use services of an
entire subsystem or package (usually tens or hundreds
of objects in the subsystem)
• Facade is also a common way to interface with non-OO
modules
• Proxy provides convenient access to an object – the
object might be on disk, in another process, on another
computer
18
Observer – a useful design technique
• Observer pattern always has at least 2 classes: Subject and
Observer
– TemperatureSensor – maintains information about the current
temperature
– TempReportWebPage – displays temperature value on a web page
• Each temperature value might appear on multiple pages
• Update each page when the TemperatureSensor changes state
page1: TempReportWebPage
temp: TemperatureSensor
report_URL : string
Update
page2: TempReportWebPage
call Update()
on each page
report_URL : string
Update
page3: TempReportWebPage
report_URL : string
Update
19
Simple class diagram for Observer
•
In the Observer Pattern:
there are links between two
kinds of concrete classes
– subjects and observers
•
•
Each observer object (such
as TempReportWebPage)
needs to register by calling
the Attach() operation on a
subject object (like
TemperatureSensor)
Each observer object will
have its Update() operation
called whenever its subject
changes state
ConcreteSubjec observers
ConcreteObserver
t
1
0..* observerState
subjectState
Update()
GetState()
ModifyState()
observerState =
Attach(Observer)
subject->GetState();
Detach(Observer
)
Notify()
subjectState = newState;
for all o in observers {
Notify();
o ->Update()
}
20
Complete class diagram for Observer
•
•
•
Observer is an abstract
interface that each
ConcreteObserver must
implement (must implement
an Update() function)
Observer objects still
register by calling the
Attach() operation on a
ConcreteSubject object
Each ConcreteObserver
object will have its Update()
operation called whenever
its ConcreteSubject
changes state
Subject
Attach(Observer)
Detach(Observer)
Notify()
observers
Observer
1
0..*
Update()
for all o in observers {
o ->Update()
}
ConcreteSubject
subjectState
GetState()
return subjectState
ConcreteObserver
observerState
Update()
observerState =
subject->GetState();
21
Why update the Observer objects?
• In the Observer Pattern, there are some objects that “care about”
the state changes within other objects
• The ConcreteObserver::Update() function might do these things:
– repaint a user interface
– check for exceeding thresholds
• So the ConcreteObserver is a place to put operations that might
clutter up a domain class
– example: any “View” class
• Or the ConcreteObserver is a place to put a command handler for a
user interface class
– button and menu handlers can be implemented as Observers of GUI
objects
22
Motivation for Observer
• An early OO user interface architecture: Model-ViewController
– A model, is an object representing data (often data about
an object in the real world)
– A view is some form of visualization of the state of the
model.
– A controller offers facilities for the user to change the
state of the model (clicking on buttons, sliding a slider,
typing in a text box, etc.)
• Some elements within the View observe the Model
– if the Model changes state, then the View may need to
update its objects and pass the changes to the user
interface implementation
• The Model observes the Controller
– after the Controller accepts command input from the
user, it needs to notify the Model to update its state
View
A 5
Z
Model
event proc1
event proc2
Controller
23
Observer implementation
• A Subject class will usually keep a linked list of pointers to its
registered Observers
– linked list: multiple View objects might observe the same Model, and
the linked list makes it easier when one of the middle objects wants to
Detach (to stop receiving notifications)
– each pointer in the list is of type Observer* (abstract type defining the
Update() operation), because the concrete types for different observers
is often quite different
• Is this necessary?
– No. In some cases, you might know that all observers have the same
type. Then the list might declared to contain ConcreteObserver*
pointers.
– In fact, the linked list could be replaced by a fixed sized pointer table or
a dynamic sized array (std::vector in C++) – especially if the set of
observers is relatively static
24
Analysis patterns
• Analysis patterns are a set of patterns that are used in
doing the initial problem analysis:
– They help answer the question “what objects should I define in
my system?”
• The Quantity pattern is from the book Analysis Patterns
by Martin Fowler
– Recording measurements and manipulating results might be
error-prone
– Each value really should be recorded with its units:
• A Money object will have both a number and an identifier to say
which currency: [19.95, “US Dollars”]; [700, “Euros”]; [100, “Yuan”]
• Length and weight also need units: [100, “miles”]; [15.5, “kg”]
25
Justification for the Quantity pattern
• A frequent problem – someone tries to perform an invalid
operation on two different types of quantities:
– adding apples to oranges, people to money, dates to time
intervals
– conversion mistakes: adding dollars to euros, inches to feet
– performing an average of a mixed bag of objects (this should
never be legal)
• Using explicit units in the design makes it easier for
someone else to understand the software later
– what does this number mean??
26
Architecture patterns
• You can save a lot of design work by reusing some welltested architectures:
– Patterns of Software Architecture: the first book on “architecture
patterns”
• An example: Client-Dispatcher-Server
– Problem: You are designing a “video on demand” service
– Your customers can order different movies, and you have video
servers in the central office that can play the movies
– When requests come in, the system needs to decide which
server will handle each request
– There is a standard “division of responsibilities” in the design
27
Client-Dispatcher-Server example
•
initial
stimulus
send_request(s)
A Customer wants a particular
Service, so
Customer::send_request() is
c: Customer
1: receive_request(c)
•
called.
This will invoke the Service (it calls the
Service::receive_request()
s: Service
1.1: sn = obtain_channel(c)
•
:ServiceNode
Assigner
1.1.2: add
NodeUser(c)
1.1.1*: get
Capacity_and_Load()
•
function for a specific Service object).
The Service object wants either to
create a new ServiceNode or (more
likely) to assign an existing
ServiceNode to the Customer.
The ServiceNodeAssigner class
makes the decision about which
ServiceNode to assign and configure.
sn: ServiceNode
1.1.4: configure
Service()
28
Client-Dispatcher-Server example
• This design uses the “Client-Dispatcher-Server” pattern:
– three classes share responsibility for managing communication
• the Server provides a set of services, but it initially registers itself
with the Dispatcher
• the Client will invoke the services provided by one or more
Servers, but it will contact the Dispatcher each time it needs a
service (to help it find the right Server)
• the Dispatcher tracks the Servers and responds to the Clients that
are trying to locate a service
• The design is relatively clean:
– Clients have a single logical point of contact
– the Servers don’t need to know anything about the assignment
policy
29
Enterprise Architecture Patterns
• Martin Fowler’s excellent book: Patterns of Enterprise
Application Architecture
– Enterprise Applications – software that uses databases
(concurrent access to persistent data)
– How do you write a Java application to manipulate and display
data from a database?
– How can you make it easier to modify the application to meet
new needs without breaking the existing code?
• Some answers:
– use layers, build facades, define proxies, encapsulate data
records, and encapsulate transactions
30
Example enterprise patterns
• How do I control the formatting of my Web pages?
– If I want to edit the page and put hooks in for dynamic data? – use
Template View (HTML page with markers for varying information)
– The page is a transform of domain data? – use Transform View
– If I need to make general “look-and-feel” changes across my web site?
– use Two Step View
– Multiple appearances for the same logical screen? – use Two Step
View
• How do I interact with the database?
– If I have a domain model that corresponds to the database tables? –
use Active Record (encapsulating database access and domain logic
into one class)
– If I have a rich domain model? – use Data Mapper
– If I’m using a Table Module? – use Table Data Gateway
31
Summary
• Design Patterns: an important set of object oriented
design concepts
– these patterns are useful in many applications
– every pattern has a documented set of “Consequences”
• Some useful sources on design patterns:
–
–
–
–
http://hillside.net/patterns/onlinepatterncatalog.htm
http://www.martinfowler.com/articles/enterprisePatterns.html
http://java.sun.com/blueprints/corej2eepatterns
http://www.headfirstlabs.com/books/hfdp/
32
Download