Introduction to Patterns
Download
Report
Transcript Introduction to Patterns
Design Patterns
CS 124
Reference: Gamma et al
(“Gang-of-4”), Design Patterns
Pattern
Describes a problem that has occurred over
and over in our environment, and then
describes the core of the solution of that
problem in a way that the solution can be
used a million times over, without ever doing
it in the same way twice.
Patterns in different professions: Architects,
Writers, others
Design Pattern
Solution to a particular kind of problem
How to combine classes and methods
Not solve every problem from first principles
Based on design experience
Use requires understanding of the appropriate
problem and being able to recognize when such
problems occur
Reuse solutions from the past
Describing a Pattern
Name
Intent/Problem
Situation (problem) and context
When to apply the pattern; conditions
Solution
Elements that make up the design, relationships,
collaboration; more a template rather than a concrete
solution
How the general arrangement of elements (classes and
objects) solves it
UML diagrams (class relationships and responsibilities)
and code implications
Describing a Pattern
Consequences
Results, variations, and tradeoffs
Critical in understanding cost/benefit
How to select design patterns
Consider how the design patterns solve design
problems
Scan intent section
Consider how patterns interrelate
Study patterns of like purpose
Examine cause of redesign
Consider what should be variable in design (what
you might want to change without redesign):
Encapsulate the concept that varies
How to use a design pattern
Read up on the pattern
Study structure, collaboration, participants
Look at sample code
Choose names of participants meaningful in the
application context
Define classes
Define application specific names for operations in
the process
Implement the operations
Selected Patterns for
Discussion
Singleton
Abstract Factory/Factory Method
Composite
Iterator
Singleton
Intent
ensure a class has only one instance, and provide a
global point of access to it
Motivation
Important for some classes to have exactly one instance.
E.g., although there are many printers, should just have
one print spooler
Ensure only one instance available and easily accessible
global variables gives access, but doesn’t keep you from
instantiating many objects
Give class responsibility for keeping track of its sole
instance
Design Solution
Defines a getInstance() operation that lets
clients access its unique instance
May be responsible for creating its own
unique instance
Singleton
static uniqueinstance
Singleton data
static getInstance()
Singleton methods…
Singleton Example (Java)
Database
Database
static Database* DB
instance attributes…
static Database* getDB()
instance methods…
public class Database {
private static Database DB;
...
private Database() { ... }
public static Database getDB() {
if (DB == null)
DB = new Database();
return DB;
}
...
}
In application code…
Database db = Database.getDB();
db.someMethod();
Singleton Example (C++)
class Database
{
private:
static Database *DB;
...
private Database() { ... }
public:
static Database *getDB()
{ if (DB == NULL)
DB = new Database());
return DB;
}
...
}
Database *Database::DB=NULL;
In application code…
Database *db =
Database.getDB();
Db->someMethod();
Implementation
Declare all of class’s constructors private
prevent other classes from directly creating an instance of
this class
Hide the operation that creates the instance behind
a class operation (getInstance)
Variation: Since creation policy is encapsulated in
getInstance, possible to vary the creation policy
Singleton Consequences
Ensures only one (e.g., Database) instance exists in
the system
Can maintain a pointer (need to create object on
first get call) or an actual object
Can also use this pattern to control fixed multiple
instances
Much better than the alternative: global variables
Abstract Factory/
Factory Method
Intent: provide an interface for creating objects
without specifying their concrete classes
Example: Stacks, Queues, and other data
structures
Want users to not know or care how these structures are
implemented (separation)
Example: UI toolkit to support multiple look-and-feel
standards, e.g., Motif, PM
Abstract class for widget, supporting class for specific
platform widget
Solutions in C++
Use of header file (class declarations) and
implementation file (method definitions) ok but
limited
Header file usually contains private declarations which are
technically part of the implementation
Change in implementation requires that the application
using the data structure be recompiled
Alternative: create an abstract superclass with pure
virtual data structure methods
Design Solution for Abstract
Factory
Factory
Product
createProduct()
virtual methods
Client
Note: this is an
abbreviated design
ConcreteProdA
ConcreteProdB
methods
methods
Participants
Factory
(Abstract) Product: declares an interface for a type
of product object
Concrete Product
implements the operations to create concrete product
objects
actual pattern includes abstract and concrete factory
classes
defines a product object to be created by the
corresponding concrete factory
implements the abstract product interface
Client: uses only Factory and Abstract Product
Stack Example (C++)
Stack class defines virtual methods
ArrayStack and LinkedStack are derived classes of
Stack and contain concrete implementations
StackFactory class defines a createStack() method
that returns a ptr to a concrete stack
push(), pop(), etc.
Stack *createStack() { return new ArrayStack(); }
Client programs need to be aware of Stack and
StackFactory classes only
No need to know about ArrayStack()
Factories in Java
Stack is an Interface
ArrayStack and LinkedStack implement Stack
StackFactory returns objects of type Stack through
its factory methods
Select class of the concrete factory it supplies to client
objects
If using info from requesting client, can hardcode selection
logic and choice of factory objects
Use Hashed Adapter Pattern to separate selection logic for
concrete factories from the data it uses to make the
selection
Abstract Factory
Consequences
Factory class or method can be altered
without affecting the application
Concrete classes are isolated
Factory class can be responsible for creating
different types of objects
e.g., DataStructure factory that returns stacks,
queues, lists, etc.
“product families”
Kinds of Patterns
Singleton and Factory are examples of
Creational Patterns
Other kinds of patterns
Structural: concerns object structure;
e.g., Composite
Behavioral: concerns object interaction and
distribution of responsibilities;
e.g., Iterator
Composite Pattern
Intent: compose objects into tree structures to
represent (nested) part-whole hierarchies
Clients treat individual objects and composition of objects
uniformly
Example: GUIs (e.g., java.awt.*)
Buttons, labels, text fields, and panels are
VisualComponents but panels can also contain
VisualComponent objects
Calling show() on a panel will call show() on the objects
contained in it
Iterator Pattern
Intent: provide a way to access the elements
of an aggregate object sequentially without
expressing its underlying representation
Example: iterators of C++ STL containers
Note that you can have several iterator objects for
a container and that the iterators are separate
classes
Creational Patterns
Abstract Factory
Builder
Factory Method
Prototype
Singleton
Structural Patterns
Adapter
Bridge
Composite
Decorator
Façade
Flyweight
Proxy
Behavioral Patterns
Chain of Responsibility
Command
Interpreter
Iterator
Mediator
Memento
And a few more …
Summary
Main point: to recognize that there are proven
solutions to problems that a designer/ programmer
may encounter
Search for such solutions first
Solutions are results of others’ experiences
Towards “standard approaches”
Although there is some merit attempting to create the
solution yourself
Becoming a design architect
Up Next: inventory of other patterns