Upload
douglas-bennett
View
214
Download
0
Embed Size (px)
Citation preview
Design PatternsDesign Patterns
What is a Design Pattern?What is a Design Pattern?
A "solution to a problem in context“; it represents a high-quality solution to a recurring problem in design
Why use Design PatternsWhy use Design Patterns
Success is more important than noveltyEmphasis on writing and clarity of
communicationQualitative validation of knowledgeGood pattern arise from practical
experienceRecognize the importance of human
dimensions in software development
Success is more important than noveltySuccess is more important than novelty
Reusing standard designs with successful track record, often outweigh the few extra performance typically available from starting from scratch.
Novelty can be a liability, because new techniques are often untested.
Emphasis on writing and clarity of Emphasis on writing and clarity of communicationcommunication
Patterns are documented both in literary style and technical document style – which makes easy communication.
Very often projects fail because developers are unable to communicate good software deign, architectures and programming practices to each other.
Using pattern improves communication and concisely articulating the structure and behavior of project.
Good patterns arise from practical Good patterns arise from practical experienceexperience
Appreciate and reward the creative progress that expert developers use to build high quality software system.
Patterns are not to replace developers creativity – instead leverage the complexity and understandability of software systems
Three Categories of PatternThree Categories of Pattern Creational – makes systems independent of how objects
are created,composed and represented– Singleton– Factory
Behavioral – deals with algorithms and assignments of responsibilities between objects– Observer– Visitor– Cache Management
Structural – are concerned with how classes and objects are composed to form larger structures– Adapter– Bridge– Façade– MVC
The Singleton PatternThe Singleton PatternCreational
SingletonSingleton
– Context: It is very common to find classes for which only one instance
should exist (singleton)
– Problem: How do you ensure that it is never possible to create more
than one instance of a singleton class?
– Forces: The use of a public constructor cannot guarantee that no more
than one instance will be created. The singleton instance must also be accessible to all classes
that require it
SingletonSingleton
Company
theCompany
Company «private»getInstance
if (theCompany==null) theCompany= new Company();
return theCompany;
«Singleton»
theInstance
getInstance
Behavioral Pattern: ObserverBehavioral Pattern: ObserverProblem When an object changes state, notify all interested
Context Multiple views of the same data (say, bar-charts and
pie-charts) must be kept consistent with changes to the underlying data without any coupling among the views
Key Participants A subject may have many dependent observers. All
observers are notified whenever the subject undergoes change
Observer: StructureObserver: Structure
Subject
Attach(Observer)Detach(Observer)Notify()
Observer
Update()
ConcreteSubject
GetState()SetState()
subjectState
ConcreteObserver
Update()
observerState
for all o in observers { o.Update()}
return subjectState
observers
subject
observerState = subject.GetState()
Observer: CollaborationsObserver: Collaborations
ConcreteSubjectA ConcreteObserverX ConcreteObserverY
SetState()
GetState()
Update()
Update()
Notify()
GetState()
Observer: ImplementationObserver: Implementation Observing more than one subject Who invokes Notify?
– Have SetState invoke Notify– Require clients of Subject invoke Notify
Dangling references to deleted subjects Call Notify only when Subject state is self-consistent How is change information transferred?
– Push Model: Subject sends all details even if not required– Pull Model: Subject sends minimal information and
Observers ask for details explicitly
Selective notification of observers
Behavioral Pattern: VisitorBehavioral Pattern: VisitorProblem Classes may be polluted with many distinct but
unrelated operations
Context Distributing operations like pretty-printing and type
checking to various AST node classes in a compiler can lead to code that is difficult to maintain
Adding a new operation would require changing all the node classes
Key Participants Package related operations from each class into a
single class, called a visitor
Visitor: StructureVisitor: StructureClient
ObjectStructure
ElementAccept(Visitor)
ConcreteElementAAccept(Visitor)OperationA()
ConcreteElementBAccept(Visitor)OperationB()
v.VisitCEB(this)
VisitorVisitCEA(ConcreteElementA)VisitCEB(ConcreteElementB)
ConcreteVisitor1VisitCEA(ConcreteElementA)VisitCEB(ConcreteElementB)
ConcreteVisitor2VisitCEA(ConcreteElementA)VisitCEB(ConcreteElementB)
v.VisitCEA(this)
Visitor: CollaborationsVisitor: Collaborations
anObjectStructureaConcreteElementA
aConcreteVisitor
Accept(aVisitor)
Accept(aVisitor) VisitCEA(aConcreteElementA)
OperationA()
VisitCEB(aConcreteElementB)
OperationB()
aConcreteElementB
Visitor: ImplementationVisitor: Implementation How does visitor add operations without changing
them?– Double dispatch: operation that gets executed depends on
the kind of request and types of two receivers(visitor and element)
– This consolidates the operations in a visitor and uses Accept() as a double dispatch operation
– Binding is run-time and extensions are easy Who is responsible for traversing the object
structure? Responsibility could be in the object structure, visitor or
a separate iterator object What about information hiding concepts?
Structural Patterns:FaçadeStructural Patterns:Façade
The Façade pattern simplifies access to a related set of objects by providing one object that communicate with the set. By doing this you are decoupling business components from one another making designs more flexible and comprehensible.
A Façade pattern enables a programmer to shield clients of classes from their complexity. This is done by providing an additional reusable object that hides most of the complexity of working with the other classes from client classes
Using a Façade design pattern enables the developer to design classes to function in a clean and separate layer which allows for easier class reuse.
Façade Class DiagramFaçade Class Diagram
A Class diagram of a Façade pattern shows the general structure and sequence flow. The client object interacts with a Façade object that provides necessary functionality by interacting with the rest of the objects.
If there is some additional functionality that is needed by only some clients, then instead of providing it directly, the Façade object may provide a method to access another object that does provide the functionality.
The façade pattern shields client classes from complexity of the class they implement simplifying the use of multiple clients.
Class DiagramClass Diagram
Façade Class DiagramFaçade Class Diagram
Implementing a FaçadeImplementing a Façade
A Façade should provide a client object with a direct reference to a implementing class that the client should know about but hide the implementations that the client should not know about.
This can be done through the use of private inner classes within the Façade classes.
Session FacadeSession Facade
Uses J2EE Session Beans to implement the façade pattern. Brings all the advantages of using a façade pattern to the
J2EE Architecture, single interface, decoupling of objects, flexibility of reuse.
A session façade also gives internet applications the advantage of calling server side business objects locally reducing network traffic between the client and the server.
The session façade also acts as a mediator between business objects decoupling their interfaces and delegating calls to different objects.
Sequence DiagramSequence Diagram
Call 1
Call 2
Call 3
Network
Façade Sequence DiagramFaçade Sequence Diagram
Call 1Call 2
Call 3
Network
Call 4
Cache ManagementCache Management
The Cache Management pattern helps increase application performance by allowing fast access to objects that would otherwise take a long time to access. The pattern achieves this by keeping a copy of objects that are retrieved from a database or involve long computations to create. Once the copy of the object is created the application references the object attributes to retrieve important data.Cache Management is deciding which and how many objects to store in memory.
A Cache Management pattern is based on the principle that keeping data in memory for fast access improves performance. This is a similar to a web browsers Cache that holds frequently visited web pages in memory for faster retrieval.
Cache Management ClassesCache Management Classes
The client is responsible for obtaining access to specified objects through a Cache Manager object.
An ObjectKey is used to identify the object to be retrieved.
The Cache Manager object handles requests for objects by calling the fetchObject method with an ObjectKey parameter. If an object exists it calls the fetchObject method. If the object needs to be created it calls the objectCreater createObject method.
Cache Management Classes Cont.Cache Management Classes Cont.
The object creator is responsible for creating objects that are not in the cache.
The Cache object is the main object responsible for managing the collection of objects. An object is added to the cache by the addObject method and objects are retrieved with the fetchObject method.
Cache Management DiagramCache Management Diagram
Cache Management ImplementationCache Management Implementation
When implementing a Cache system you must consider using data structures that quickly find objects through it’s ObjectKey.
Search operations should be faster then add or remove operations since they will be used most frequently.
Cache Management optimization involves choices about statistical analysis, queuing theory, and performance tuning issues.
Structural patterns:Model-View-Structural patterns:Model-View-ControllerController
The MVC design pattern is designed to decouple data representation, application behavior, and presentation.
This pattern helps eliminate the problems that can happen during maintenance changes by making the components independent of each other.
Class reuse can be difficult or impossible when a class is coupled to another class making them dependent.
Model-View-Controller ContModel-View-Controller Cont
MVC was originally used in Smalltalk and can de defined as:
Model - The model represents enterprise data and the business rules that govern access to and updates of this data. Often the model serves as a software approximation to a real-world process, so simple real-world modeling techniques apply when defining the model.
Model-View-Controller Cont IIModel-View-Controller Cont II
View -The view renders the contents of a model. It accesses enterprise data through the model and specifies how that data should be presented. It is the view's responsibility to maintain consistency in its presentation when the model changes. This can be achieved by using a push model, where the view registers itself with the model for change notifications, or a pull model, where the view is responsible for calling the model when it needs to retrieve the most current data.
Model-View-Controller Cont IIIModel-View-Controller Cont III
Controller – Components of the controller receive the client requests, process the request, or forward the request to other components that process the data, and then direct the request to a view component. Any web application component such as a JSP, Servlet, or EJB could be a controller component. Servlets are usually used because they are intended to receive requests and respond to clients.
MVC DiagramMVC DiagramModel
-Encapsulate Application State-Respond to State Queries
-Exposes Application functionality-Notify views of changes
View-Displays the Models
-Requests updates from Models-Sends user info to Controller
Controller-Defines application behavior-Maps user action to Model-Selects view for response
Method Invocation Event
MVC ImplementationMVC Implementation
MVC achieves decoupling using the controller to forward requests between the components involved.
The Request Dispatcher method is used in the controller to forward the request or response information from other components and to display the Views that capture the Model output.
This can also be achieved through a framework such as struts which uses the MVC pattern as it’s model for operation flow.
Creational patterns:Factory Creational patterns:Factory MethodMethod
Define an interface for creating an object, but let subclasses decide which class to instantiate.
Lets a class defer instantiation to subclasses.
Factory Method Cont.Factory Method Cont.Document ExampleDocument Example
Consider a framework that can present multiple documents to the user.
Abstract classes Application and DocumentCreate two classes DrawingApplication and
DrawingDocument.Application class will create documents
when required – Open or New from menu.
Factory MethodFactory MethodDocument Example cont.Document Example cont.
Application class only knows when a new document should be created, not what kind of document.
It knows of the abstract classes but cannot instantiate them.
When to Use the Factory MethodWhen to Use the Factory Method
A class cannot anticipate the class of objects it must create
A class wants its subclasses to specify the objects it creates.
Classes delegate responsibility to one of several helper subclasses and you want to localize the knowledge of which helper subclass is the delegate.
StructureStructure
Creational patterns:BridgeCreational patterns:Bridge
Decouple an abstraction from its implementation so that the two can vary independently.
Bridge Cont.Bridge Cont.
When an abstract class can have several implementations, inheritance is used.
Inheritance binds an implementation to the abstraction permanently, which makes modifications difficult.
Bridge ExampleBridge Example
Consider a Window abstraction.User should be able to write applications on
X Window System and IBM’s Presentation Manager (PM).
Inheritance has two disadvantages in this case.
Inheritance DisadvantagesInheritance Disadvantages
If you needed an IconWindow subclass of Window, you will need two new classes for implementation.
Code is now platform-dependent
Window DiagramWindow Diagram
Basic design of first implementation.
Implement IconWindowImplement IconWindow
How Bridge fixes this.How Bridge fixes this.
The Bridge pattern addresses these problems by putting the Window abstraction and its implementation in separate class hierarchies.
When to use bridgeWhen to use bridge
You want to avoid a permanent binding between abstraction and its implementation.
Both the abstractions and their implementations should be extensible by subclassing.
Code should not have to be recompiled if changes of implementation or abstraction occur.
When to use Bridge cont.When to use Bridge cont.
You want to share implementation among multiple objects and you want to hide this from the client.
StructureStructure
Creational patterns:AdapterCreational patterns:Adapter
Convert the interface of a class into another interface clients expect.
Lets classes work together that couldn’t otherwise because of incompatible interfaces.
Drawing ClassDrawing Class
Consider a drawing editor that can draw basic shapes.
LineShape and PolygonShape classes are easy to implement.
TextShape is harder to implement so use third party object.
How do you bring that object into the framework?
Two WaysTwo Ways
Inherit Shape’s interface and TextView’s implementation.
Composing a TextView instance within a TextShape and implementing TextShape in terms of TextView’s interface.
When to use AdapterWhen to use Adapter
You want to use an existing class, and its interface does not match the one you need.
You want to create a reusable class that cooperates with unrelated or unforeseen classes.
You need to use several existing subclasses , but it’s impractical to adapter their inteface by subclassing every one.
Multiple InheritanceMultiple Inheritance
CompositionComposition