SDA Lec5
SDA Lec5
SDA Lec5
Lecture 5
5. Design Patterns
In software engineering, a design pattern is a
general repeatable solution to a commonly occurring
problem in software design.
A design pattern isn't a finished design that can be
transformed directly into code.
It is a description or template for how to solve a
problem that can be used in many different situations.
Design patterns provide general solutions,
documented in a format that doesn't require specifics
tied to a particular problem.
Patterns solve software structural problems
like:
Abstraction,
Encapsulation
Information hiding
Separation of concerns
Coupling and cohesion
Separation of interface and implementation
Single point of reference
Divide and conquer
Patterns also solve non-functional problems
like:
Changeability
Interoperability
Efficiency
Reliability
Testability
Reusability
Benefits of Design Patterns
Communication & vocabulary
Testability
Maintainance
Extensibility
Loosecoupling
Downsides of Design Patterns
Hard to teach and learn
Hard to know when to apply
Require good knowledge of OOP
Activity
Create an activity diagram of issue of a book.
Why do we use Design Patterns?
They provide you with a way to solve issues related to
software development using a proven solution.
Design patterns make communication between designers
more efficient. Software professionals can immediately
picture the high-level design in their heads when they
refer the name of the pattern used to solve a particular
issue when discussing system design.
5.1. Types of Pattern
There are 3 types of pattern …
Creational: These design patterns are all about class
instantiation. This pattern can be further divided into class-
creation patterns and object-creational patterns
Structural: Structural patterns organize classes and help
separating the implementations from their interfaces.
Behavioral: address problems of assigning responsibilities
to classes. These design patterns are all about Class's objects
communication. Behavioral patterns are those patterns that
are most specifically concerned with communication
between objects.
Creational:
These design patterns are all about class instantiation. This
pattern can be further divided into class-creation patterns and
object-creational patterns
Abstract factory
Factory method
Singleton
Builder
Object pool
Prototype
Structural:
Structural patterns organize classes and help separating the
implementations from their interfaces.
Adapter
Bridge
Composite
Decorator
Facade
Flyweight
Proxy
Behavioral Patterns
Behavioral patterns simplify the communication between
objects in order to increase flexibility and decoupling.
Chain of Responsibility
Command
Interpreter
Iterator
Mediator
Memento
Observer
State Strategy
Template Method
5.2. Patterns, Architectures &
Frameworks
There can be confusion between patterns, architectures
and frameworks.
Let’s try to distinguish them:
Architectures model software structure at the highest
possible level, and give the overall system view. An
architecture can use many different patterns in different
components
Patterns are more like small-scale or local
architectures for architectural components or sub-
components
Frameworks are partially completed software
systems that may be targeted at a particular type of
application. These are tailored by completing the
unfinished components.
Pattern Name: Describes the essence of the pattern in
a short, but expressive, name
Intent: Describes what the pattern does
Problem: Provides an example of a problem and how
the pattern solves that problem
Applicability Lists: the situations where the pattern is
applicable
Structure: Set of diagrams of the classes and objects
that depict the pattern
Example: describes some real life examples of the same
type.
5.5. Pattern: Singleton (Creational)
Pattern Name: Singleton
Intent: How can we guarantee that one and only one
instance of a class can be created and has a global
access to it?
Problem: In some applications it is important
to have exactly one instance of a class,
Applicability:
Create a class with a class operation getInstance().
When class is first accessed, this creates relevant
object instance and returns object identity to client.
On subsequent calls of getInstance(), no new
instance is created, but identity of existing object is
returned.
Singleton Structure
Singleton Object identifier for singleton
instance, class scope or static
-uniqueInstance
-singletonData Returns object identifier for
+getInstance( ) unique instance, class-scope
+getSingletonData( ) or static
+singletonOperation( ) Private constructor only accessible
-Singleton( ) via getInstance()
getInstance( ) {
if ( uniqueInstance == null )
{ uniqueInstance = new Singleton( ) }
return uniqueInstance
}
Example
There can be a single configuration manager or error manager
in an application that handles all problems instead of creating
multiple managers.
Example: Code
Class Singleton {
private static Singleton uniqueInstance = null;
private Singleton( ) { .. } // private constructor
public static Singleton getInstance( ) {
if (uniqueInstance == null)
uniqueInstance = new Singleton();
// call constructor
return uniqueInstance;
}
}
Singleton
Advantages
Singleton controls access to the system resource.
It ensures there is only one object available in the system
control state.
Adaptor (structural)
The Adapter design pattern helps two incompatible
interfaces work together without changing them.
$someDependency = new SomeDependency();
$adaptee = new Adaptee($someDependency);
$adapter = new Adapter($adaptee);
$client = new Client($adapter);
$client->doSomething();
Facade
subsystem classes
<<façade>> Pattern Name
SecurityManager
+addAccessRight()
+addActor()
+addActorRole()
+removeActor()
AccessRight ActorRole
+addAccessRight() +addActorRole()
Actor
+addActor()
+removeActor() Method not in Facade
+changeSalary()
Comments
Clients communicate with the subsystem by sending
requests to Façade which forwards them to the
appropriate subsystem object(s).
Although subsystem objects perform actual work,
Façade may have to translate its interface to subsystem
interfaces.
Clients that use the Façade don’t have to access its
subsystem objects directly.
5.7. Pattern: Mediator (Behavioral)
Problem:
How can we deal with two or more classes
which sometimes interact, but can also be used
separately?
Solution: Mediator promotes loose coupling
by keeping objects from referring to one another
explicitly. Put each interaction between objects
in a separate (Mediator) class. This class
should have references to the objects.
A pattern for two objects which exist independently but
have some coupling. This coupling is placed in its own
class.
Used by e.g. ActionListener in graphics which couples
together two graphical objects, e.g. window & button
Mediator Structure
1 mediator
Mediator Colleague
*
ConcreteMediator Concrete Concrete
Colleague1 Colleague2
*
Colleagues send and receive requests from a Mediator
object. The mediator implements the cooperative
behavior by routing requests between appropriate
colleagues.
Example: Top-Down Design
1 mediator
Mediator Colleague
*
File_Selector Browser Button Text_Field
* *
My_Application
Comments
Façade, unlike Mediator, abstracts a subsystem of
objects to provide a convenient interface.
Unidirectional. Façade objects make requests of the
subsystem, but not vice-versa.
Mediator enables cooperative behaviour, that colleagues
don’t or can’t provide. Multidirectional.
Observer pattern and Mediator both receive
notification of changes.
Observer does so through an abstract mechanism.
Allows source of notification to be independent of its
observers.
In Mediator, the source must know its mediator. This
makes it possible for mediator to define reactions to
each stimulus.
5.8. Pattern: Observer (Behavioral)
Name: Observer
Problem: Define a one-to-many dependency
among objects so that when one object
changes state, all of its dependents are
notified and updated automatically.
Solution: MVC, but refined by separating
abstract from concrete subjects and observers
*
Subject Observer
attach(Observer) Update()
detach(Observer)
notify() for all o in
observers {
o.update( ) }
ConcreteObserver
ConcreteSubject *
observerState
subjectState() update()
getState()
setState()
return observerState =
subjectState subject.getState( )
ConcreteSubject notifies its observers whenever a
change occurs that could make its observers state
inconsistent with its own
After being informed of change, a ConcreteObserver
queries the subject to reconcile its state with subjects.
Observer object that initiates change request
postpones its update until it gets notification from
subject. Notify() is not always called by subject. Can be
called by an observer, or any other object.
Pattern is well known, has wide range of variants
aConcrete aConcrete aConcrete
Subject: Subject: Subject:
setState( )
notify( )
update( )
getState( )
update( )
getState( )
5.9. Pattern: Mock Object
A pattern where coupling an objects coupling to another
complex object is replaced by coupling to a simplified
proxy.
C.f. dummy methods in whishful thinking
Coupling between objects could well be an interface.
Then the mock and real objects implement this interface.
Used e.g. in testing objects. (see Section 8)
5.10 Pattern: Factory
Name: (Abstract) Factory
Problem: Provide an interface for creating
families of related or dependent objects
without specifying their concrete classes.
Control instantiation
Singleton is a special case of Factory where
only one object can be created.
Factory Structure
AbstractFactory
FactoryMethod() Product =
AbstractProduct AnOperation() FactoryMethod()
ConcreteProduct1 ConcreteFactory
FactoryMethod()
return new
ConcreteProduct()
Normally, a single instance of a ConcreteFactory
class is created at runtime.
This creates product objects having a particular
implementation.
To create different product objects, clients should use
a different concrete factory.
AbstractFactory defers creation of product objects
to its ConcreteFactory subclasses.
Factory Class Model
Client RequiredClass
create objects
MyClass
createObjectOfRequiredClass():RequiredClass
Interface CarFactory {
Public Car makeCar(String b) throws Exception;
}
Comments
Abstract Factory classes are often implemented with the
Factory Method pattern.
Can also be implemented using the Prototype pattern.
A concrete factory is often a Singleton.
5.11 Command
Name: Command
Problem: Need a flexible organization for
methods that allows them to be context
sensitive in a structured way.
Solution: Place behaviour /operation in an
own class instead of in a method.
Examples
Undo. It’s difficult to undo effects of an arbitrary method.
Methods vary over time.
1 receiver
Receiver
ConcreteCommand
Action() Receiver.Action()
Execute()
State
Client creates a ConcreteCommand object and
specifies its receiver.
An Invoker object stores the ConcreteCommand
object
The invoker issues a request by calling Execute on the
command. When commands are undoable,
ConcreteCommand stores state for undoing the
command before invoking Execute
ConcreteCommand object invokes operations on its
receiver to carry out request
aClient aCommand anInvoker aReceiver
new Command(aReceiver)
storeCommand(aCommand)
Execute()
Action()
Comments
Pattern replaces function pointers (passing functions as
parameters) which is not available in some languages.
Pattern allows a class to call a receivers routine without
knowledge of it. Gives high degree of decoupling between
caller and callee.
Command (Cont.)
Client:
Command command = Command.getCommand
(…);
Command.execute();
A Factory method first gives a Command object (means
object can depend on current situation)
Then call execution command execute()
class Command {
public void execute() {
if (check-something) { //menu item
selectable?
this.getParameters(); //preparation
getTarget1().action1(); //do something
}
else
// do something else,
// like other action or target
}
}
Related Patterns
A Memento pattern can be used the keep the state a
command needs to undo its effect.
A command that must be copied before being placed on
the history list acts as a Prototype pattern.
Guidelines Checklist
Is there a pattern that addresses my problem?
Does the pattern provide an acceptable solution?
Is there a simpler solution? (pattern overuse)
Is the context of the pattern consistent with my
problem?
Are the consequences of using the pattern
acceptable?
Are there forces in my environment that conflict with
the use of the pattern?
Benefits and Dangers
+ support software reuse
+ language for discussing high-level problems
+ access to experience and knowledge
- limit creativity?
- needs a culture of reuse
- needs organisational education