0% found this document useful (0 votes)
111 views

Patterns 1 Intro

This document discusses three design patterns: Abstract Factory, Composite, and Strategy. Abstract Factory provides a way to encapsulate object creation so that clients don't need to know the specific classes that are instantiated. Composite treats individual and group objects uniformly. Strategy allows an algorithm to be changed independently of clients that use it. Design patterns provide reusable solutions to common programming problems and promote open-closed and single responsibility principles.

Uploaded by

api-26214845
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
111 views

Patterns 1 Intro

This document discusses three design patterns: Abstract Factory, Composite, and Strategy. Abstract Factory provides a way to encapsulate object creation so that clients don't need to know the specific classes that are instantiated. Composite treats individual and group objects uniformly. Strategy allows an algorithm to be changed independently of clients that use it. Design patterns provide reusable solutions to common programming problems and promote open-closed and single responsibility principles.

Uploaded by

api-26214845
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 38

Design

Patterns
David Talby
This Lecture
■ What is it all about?
■ Abstract Factory
■ Composite
■ Strategy
Introduction
■ O-O Design is Hard
■ Errors are expensive
■ Reuse experts’ designs

■ Pattern = Documented experience


Expected
Benefits
■ Finding the right classes
■ Finding them faster
■ Common design jargon
■ Consistent format
■ Coded infrastructures
O-O
Programming
■ An interface is a contract to clients.
■ A class implements interface(s).
■ Objects are instances of classes.
■ Objects are only accessed through
their public interfaces.
■ Only two relations between classes:
Inheritance and composition
Object
Relationships
■ Inheritance: Static and efficient, but
exposes and couples modules
■ Composition: Hides more from client
and can change dynamically
■ Gang of Four:
“Favor composition over inheritance”
■ Dijkstra: “Most problems in
computer science can be solved by
another level of indirection”.
Designing for
Change
■ The Open-Closed Principle
■ Non-clairvoyance
■ Key Issue: Prepare for change!

■ Well, prepare for what?


Causes of
Redesign
■ Dependence on hardware or
software platform
■ Dependence on representation or
implementation
■ Specifying a class upon creation
■ Algorithmic dependence
■ Tight coupling
■ Overuse of inheritance
■ Inability to alter classes easily
Pattern
Categories
■ Creational - Replace explicit
creation problems, prevent
platform dependencies
■ Structural - Handle unchangeable
classes, lower coupling and offer
alternatives to inheritance
■ Behavioral - Hide implementation,
hides algorithms, allows easy and
dynamic configuration of objects
Pattern of
Patterns
■ Encapsulate the varying aspect
■ Interfaces

■ Inheritance describes variants

■ Composition allows a dynamic

choice between variants


Criteria for success:
Open-Closed Principle
Single Choice Principle
1. Abstract
Factory
■ A program must be able to choose
one of several families of classes
■ For example, a program’s GUI
should run on several platforms
■ Each platform comes with its own
set of GUI classes:
WinButton, WinScrollBar, WinWindow
MotifButton, MotifScrollBar, MotifWindow
pmButton, pmScrollBar, pmWindow
The
Requirements
■ Uniform treatment of every button,
window, etc. in the code
◆ Easy - Define their interfaces:

■ Uniform object creation


■ Easy to switch between families
■ Easy to add a family
The Solution
■ Define a Factory - a class that
creates objects:

class WidgetFactory {
Button* makeButton(args) = 0;
Window* makeWindow(args) = 0;
// other widgets…
}
The Solution II
■ Define a concrete factory for each
of the families:
class WinWidgetFactory {
Button* makeButton(args) {
return new WinButton(args);
}
Window* makeWindow(args) {
return new WinWindow(args);
}
}
The Solution III
■ Select once which family to use:
WidgetFactory* wf =
new WinWidgetFactory();
■ When creating objects in the code,
don’t use ‘new’ but call:
Button* b = wf->makeButton(args);
■ Switch families - once in the code!
■ Add a family - one new factory, no
effect on existing code!
The Big (UML)
Picture
The Fine Print
■ The factory doesn’t have to be
abstract, if we expect a remote
possibility of having another family
■ Usually one factory per application,
a perfect example of a singleton
■ Not easy to extend the abstract
factory’s interface
Known Uses
■ Different operating systems
(could be Button, could be File)
■ Different look-and-feel standards
■ Different communication protocols
Pattern of
Patterns
■ Encapsulate the varying aspect
■ Interfaces

■ Inheritance describes variants

■ Composition allows a dynamic

choice between variants


Criteria for success:
Open-Closed Principle
Single Choice Principle
2. Composite
■ A program must treat simple and
complex objects uniformly
■ For example, a painting program
has simple objects (lines, circles
and texts) as well as composite
ones (wheel = circle + six lines).
The
Requirements
■ Treat simple and complex objects
uniformly in code - move, erase,
rotate and set color work on all
■ Some composite objects are
defined statically (wheels), while
others dynamically (user selection)
■ Composite objects can be made of
other composite objects
■ We need a smart data structure
The Solution
■ All simple objects inherit from a
common interface, say Graphic:
class Graphic {
void move(int x, int y) = 0;
void setColor(Color c) = 0;
void rotate(double angle) = 0;
}
■ The classes Line, Circle and others
inherit Graphic and add specific
features (radius, length, etc.)
The Solution II
■ This new class inherits it as well:
class CompositeGraphic
: public Graphic,
public list<Graphic>
{
void rotate(double angle) {
for (int i=0; i<count(); i++)
item(i)->rotate();
}
}
The Solution III
■ Since a CompositeGraphic is a list,
it had add(), remove() and count()
methods
■ Since it is also a Graphic, it has
rotate(), move() and setColor() too
■ Such operations on a composite
object work using a ‘forall’ loop
■ Works even when a composite
holds other composites - results in
a tree-like data structure
The Solution IV
■ Example of creating a composite:
CompositeGraphic *cg;
cg = new CompositeGraphic();
cg->add(new Line(0,0,100,100));
cg->add(new Circle(50,50,100));
cg->add(t); // dynamic text graphic
cg->remove(2);

■ Can keep order of inserted items if


the program needs it
The GoF UML

■ Single Inheritance
■ Root has add(), remove() methods
The Fine Print
■ Sometimes useful to let objects
hold a pointer to their parent
■ A composite may cache data about
its children (count is an example)
■ Make composites responsible for
deleting their children
■ Beware of circles in the graph!
■ Any data structure to hold children
will do (list, array, hashtable, etc.)
Known Uses
■ In almost all O-O systems
■ Document editing programs
■ GUI (a form is a composite widget)
■ Compiler parse trees (a function is
composed of simpler statements or
function calls, same for modules)
■ Financial assets can be simple
(stocks, options) or a composite
portfolio
Pattern of
Patterns
■ Encapsulate the varying aspect
■ Interfaces

■ Inheritance describes variants

■ Composition allows a dynamic

choice between variants


Criteria for success:
Open-Closed Principle
Single Choice Principle
3. Strategy
■ A program must switch between
complex algorithms dynamically
■ For example, a document editor
has several rendering algorithms,
with different time/beauty tradeoffs
■ Word is a common example
The
Requirements
■ Algorithms are complex, would be
havoc to have them inside the one
Document class
■ Switch algorithms dynamically
■ Easy to add new algorithms
The Solution
■ Define an abstract class that
represents an algorithm:
class Renderer {
void render(Document *d) = 0;
}
■ Each specific algorithm will be a
descendant class
FastRenderer, TexRenderer, …
The Solution II
■ The document itself chooses the
rendering algorithm:
class Document {
render() {
renderer->render(this);
}
setFastRendering() {
renderer = new FastRenderer();
}
private: Renderer *renderer;
}
The GoF UML
The Fine Print
■ Inheriting a strategy would deny a
dynamic switch
■ Some strategies may not use all
information passed from Context
■ Strategies can be stateless, and
then they can be shared
■ In some cases strategy objects are
optional
Known Uses
■ Document rendering programs
■ Compiler code optimizations
■ Different heuristic algorithms
(games, portfolio selection)
■ Different memory management
schemes (Booch components)
■ Validation of dialog boxes (optional
strategies, Borland ObjectWindows)
Pattern of
Patterns
■ Encapsulate the varying aspect
■ Interfaces

■ Inheritance describes variants

■ Composition allows a dynamic

choice between variants


Criteria for success:
Open-Closed Principle
Single Choice Principle
Summary
■ Experience is required to see
these patterns when they occur in
your application
■ It’s worth looking for them -
someone else has already done a
major part of your job!
■ Patterns are practical example of
the O-O approach’s usefulness
■ “Catalog” of 23 patterns on Intranet

You might also like