30
Design Patterns SWE 619 Software Construction Fall 2008

Design Patterns SWE 619 Software Construction Fall 2008

Embed Size (px)

Citation preview

Design Patterns

SWE 619Software Construction

Fall 2008

2

Design Patterns

Why should we study patterns? Standard solutions to common

problems Provide a vocabulary for

programmers Bag of tricks!

Essential for every programmer

3

What is a design pattern? It is a design technique geared to a

particular, common problem Example: suppose you need to limit objects

to only single, logicially distinct instances What does it provide?

Optimization (faster execution, lesser memory storage)

Flexibility (remove dependency) Easier for clients to use your classes

4

Downside?

Increased complexity Patterns are not for free Contrast better performance and

flexibility of use with increased difficulty in implementing/maintaining your code

Judgment call, when to use patterns

5

Use of substitution principal

Many patterns use subtypes while relying on substitution principal Assume that subtypes will conform to

super type specs Clients need not know which subtype is

being used Types can be changed during

execution without requiring client code to change

6

Types of patterns Originally proposed by Erich Gamma et

al. in GOF book Three main types of patterns:

Creational patterns: Factory pattern (PolyGen), Singleton, Prototype etc.

Structural patterns: Flyweight, Bridge, Adaptor, Proxy, Façade etc.

Behavioral patterns: Iterator, Command, Strategy, Template etc.

We’ll look at patterns covered in Liskov 15

7

Factory Pattern

Hides details of object creation. Why?

Do not want clients burdened with deciding which object to use.

Client code is based on supertype specs Easier to replace types

Use a factory method to create objects

8

Factory method

Is it a constructor? NO Factory may call a constructorEarlier client code:

Poly p = new DensePoly(…);Poly q = new SparsePoly(…);

New client code:Poly p = PolyProcs.makePoly(); Poly q = PolyProcs.makePoly();

Client

P

Q

Client

P

Q

Factory

9

Factory Method Benefits Eliminates the needs to bind application

classes into your code. Client deals with interfaces instead of specific

objects Client may use any class that implements that

interface

Enables subclasses to provide extended versions of an object creating an object inside a factory is more

flexible than creating an object directly in the client.

10

When to Use When a class cannot anticipate the

class of objects it must create. When 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 subclasses is the delegate.

11

Creation of compatible types Example:

There are 4 types of objects- SparsePoly, DensePoly, SparseMatrix and DenseMatrix

SparsePoly can only be used with SparseMatrix DensePoly can only be used with DenseMatrix How can we restrict client code to only use

compatible objects? Solution: Use related factories (f1, f2)

f1 only creates SPoly and SMatrix and f2 only creates DPoly and DMatrix [Figure 15.3]

12

Compatible types [fig 15.3]

M P

Factory Poly Matrix

SPoly DPoly SMatrix DMatrixF1 F2

13

Other Factory Patterns Builder

Constructs a collection of objects Prototype

Provides method to obtain new object of same type as prototype

Differs from clone(), in that objects are typically in an initial state

Iteration Every Iterator is a factory method Produces a generator object satisfying

Iterator interface

14

Flyweight Pattern When

Lots of occurrences, need to be shared Storage costs are high because of the quantity

of objects The application doesn't depend on object

identity. Naïve approach: create new instance each time Smarter approach: Create only the first time

Benefit (Possibly) Less memory usage (Possibly) Better performance

15

Liskov example 15.4public class Word {

// Overview: …private static Map map; // maps strings to wordspublic static Word makeWord (String s) // factory //E: returns the word corresponding to sprivate Word (String s) // private to exclude client //E: Makes this to be the word corr. to spublic String mapWord (Context c) //E: Returns the string corr. to this // in the form suitable for context c

16

2 variations Key table is hidden from the user

Client need not know if objects are being shared

Example on previous slide Key table is visible to clients

When there are other uses for the table E.g. clients need to iterate over all

instances. Example on next slide

17

Figure 15.5public class Ident {

// O: …Ident (String s) // package private constructor

}public class IdentTable {

//O: …public IdentTable() // Note: public constructor //E: makes this empty IdentTablepublic Ident makeReserved(String s) //Nonstatic Ident factorypublic Ident makeNonReserved (String s)public Iterator idents() // publicly accessible iterator

}

18

State Pattern

When to use Change the rep periodically for your

data abstraction E.g.: Liskov’s sets are small initially,

so use Vector for rep, but if grow to large sizes, use HashSet for rep

How to handle this composite representation?

19

LiskovSet example Rep

Before: Vector els; Now: Vector els; HashSet h;

One (undesirable) approach: Insert elements into both these objects – gag!

Another (undesirable) approach: Declare els as:

Object els; (not Vector els or HashTable els). Depending upon instance, call the right

method.

20

What’s wrong with this approach? Ugly! Programmer is doing the job of runtime

system Need a better approach: State pattern Define a new interface SetState

Needs all the functionality to manipulate Set SmallSet and BigSet implement the interface

Rep: SetState els; Now, dispatching is done by runtime sys

21

Figure 15.7public class Set { //rename LiskovSet

private SetState els;private int t1; // threshold for growingprivate int t2; // threshold for shrinkingpublic Set () { els = new SmallSet(); } // set the thresholds

public boolean empy() { return els.size() == 0; }public void insert (Object x) {

int sz = els.size();els.insert(x);if (sz == t1 && els.size() >t1 && !(els instanceOf

BigSet) els = new BigSet(els);

} // note state switch in context object, eg Set

22

Fig 15.7 continuedpublic interface SetState {

//O: SetState is used to implement LiskovSet; it provides most// of the Set methods. SetState objects are mutable

}public class SmallSet implements SetState {

// implementation similar to that shown in fig 5.6}public class BigSet implements SetState {…}

23

Alternate Approach: Switch State in the State Objects Subtypes of state type could detect need for

change and modify containing object directly. Implies state object (eg BigState) would need

to alter context object rep (eg els in Set) Not necessarily a desirable dependency

if (state too small) // in BigState remove() return new SmallState(…);}else return this;

24

Bridge Pattern

Consider the Poly hierarchy:

How do I extend Poly?

Poly

SparsePoly DensePoly

Poly

SparsePoly DensePoly

MyPoly

Poly

SparsePoly DensePoly

MyPoly

25

What’s wrong? Two different uses of inheritance

Conflict between them Solution?

Split the type Figure 15.8

Not a state pattern (though rep can be switched)

The architecture splits the hierarchy! Works for Poly as well as Set

26

Figure 15.8

Set

ExtSet

SetState

SmallSet BigSet

27

Strategy and Command Patterns Allow use of procedures as objects Strategy is for when using context has

an expectation about a procedure Examples: Adder, Comparator, Filterer

Command expects only an interface Example: Runnable

Often useful for procedures to be “closures” A closure prebinds some arguments Example: Filterer g = new LTFilterer(100);

28

Adaptor, Proxy, Decorator Patterns Interposing an object between client and existing

object Example: lookup(String s) method that returns all

associated objects Adaptor: Goal is to provide client-specified API to

existing object Example: lookup() only returns one object

Proxy: No change to API; Goal is control Example: Registry for lookup() resides across network

Decorator: Enhanced API Example: add additional reverseLookup(Object obj)

method Example: Bloch’s Instrumented Set wrapper example (p

84)

29

Publish/Subscribe Patterns Object of interest called a “subject” Objects interested in subject are

“observers” Observer Pattern

Subject maintains list of observers Observers join/leave the list

Pull Observers notified of change API for observers to obtain more data

Push Observers get data with notification

30

More Publish/Subscribe Patterns Inserting a mediator decouples subject

from observers Allows details of communication to be

separated from both subject and observers White Board

Decouples the caller from the identity of objects that provide a service.

Posting/Obtaining information Form of multicast