The Strategy Pattern Jay Urbain, Ph.D. urbain@msoe.edu 1 Review - - PowerPoint PPT Presentation

the strategy pattern
SMART_READER_LITE
LIVE PREVIEW

The Strategy Pattern Jay Urbain, Ph.D. urbain@msoe.edu 1 Review - - PowerPoint PPT Presentation

The Strategy Pattern Jay Urbain, Ph.D. urbain@msoe.edu 1 Review What problems are we trying to avoid? 2 Review What problems are we trying to avoid? l Class explosions l Code duplication l Tight Coupling l Poor Cohesion What


slide-1
SLIDE 1

The Strategy Pattern

1

Jay Urbain, Ph.D. urbain@msoe.edu

slide-2
SLIDE 2

Review

What problems are we trying to avoid?

2

slide-3
SLIDE 3

Review

What problems are we trying to avoid?

l Class explosions l Code duplication l Tight Coupling l Poor Cohesion

What do we want

to achieve?

3

slide-4
SLIDE 4

Review

What problems are we trying to avoid?

l Class explosions l Code duplication l Tight Coupling l Poor Cohesion

What do we want

to achieve?

l Modifiable behaviors l Ease of maintenance l High cohesion l Loose coupling

4

slide-5
SLIDE 5

Applying the Strategy Pattern

Leave behavior that is truly

shared in abstract classes. Isolate behavior(s) that vary and declare interfaces that define those behaviors. Implement the behaviors in separate concrete classes whose references can be passed to a Duck constructor.

5

<<abstract>> Duck Mallard

Duck Mallard(name: String) : void

SimUDuck v5 + urbain version

slide-6
SLIDE 6

Consider Collections.sort()

Collections.sort() uses a reference

to a concrete class that implements the Comparable interface, and thus the behavior of the compare() method. Depending on the strategy of the compareTo() method in the concrete class, different sorting will be used by Collections.sort(). The comparison strategy is decoupled from the Collections.sort() method itself.

6

slide-7
SLIDE 7

Consider Collections.sort()

7

// method prototype void Collections.sort(List<T> list) // usage: get highest priority type for domain Collections.sort( freebaseMqlEntityList ); Implementation: public class FreebaseMqlEntity implements Comparable<FreebaseMqlEntity> {

@Override public int compareTo(FreebaseMqlEntity arg0) { if( this.getPriority() < arg0.getPriority() ) { return -1; } else if( this.getPriority() > arg0.getPriority() ) { return 1; } else { return 0; } }

slide-8
SLIDE 8

The Strategy Design Pattern in its general form:

ConcreteStrategy classes implement specific behaviors The Context is the class that encapsulates and uses a specific behavior, or Strategy. A Strategy is an interface that defines a behavior

slide-9
SLIDE 9

Applying the Strategy Pattern: step 1

The Strategy Pattern is a behavioral pattern usually considered and applied at design-time. Premise: Your application requires similar objects whose behavior varies.

9

slide-10
SLIDE 10

Applying the Strategy Pattern: step 2

As a designer, you watch for inheritance patterns that result in excessive behavior overrides and/or code duplication among classes.

10

slide-11
SLIDE 11

Applying the Strategy Pattern: step 3

Leave behavior that is truly

shared in abstract classes. Isolate behavior(s) that vary and declare interfaces that define those behaviors. Implement the behaviors in separate concrete classes whose references can be passed to a Duck constructor.

11

<<abstract>> Duck Mallard

Duck Mallard(name: String) : void

SimUDuck v5 + urbain version

slide-12
SLIDE 12

Inside a concrete Duck class

public class Mallard extends Duck { // constructor public void Mallard(String name) { // create some (concrete) behaviors super(name, new CircularSwimming(), new StandardQuacking()); …

12

slide-13
SLIDE 13

Inside a an abstract Duck class

public abstract class Duck{ SwimBehavior sb; QuackBehavior qb; String name; // constructor public void Duck(String name, SwimBehavior sb, QuackBehavior qb) { this.name = name; swimBehavior = sb; quackBehavior = qb; } // centralize implementation of behaviors in top-level classes // avoid duplication of behavior in subclasses. public void swim() { swimBehavior.swim(); // invoke the specific behavior } ...

13

slide-14
SLIDE 14

Other good design principles we visited

Code to the highest level of abstraction possible:

i.

ArrayList<Thing> = new ArrayList<Thing> // bad

ii.

List<Thing> = new ArrayList<Thing> // good

iii.

Collection<Thing> = new ArrayList<Thing> // better Example: List<Duck> duckList = new ArrayList<Duck>(); Duck d1 = new Mallard(“daffy”): duckList.add( d1 ); Duck d2 = new RubberDuck(“donald”): duckList.add( d2 ); for(Duck duck : duckList) { System.out.println( d.getName() ); d.quack(); d.swim(); }

slide-15
SLIDE 15

Strategy is a Behavioral Design Pattern

The Strategy pattern allows for selection of specific

behavioral algorithms at runtime, since the selected strategy is just an attribute of the class using the Strategy.

l We can select particular behavioral strategies when

we construct the Ducks!

l And since the swim() or quack() behaviors of Duck are

just attributes (references) to concrete Strategy classes, we could easily change the behaviors at any time with a simple setSwimBehavior() mutator method! – Rubber duck behaves like Mallard!

slide-16
SLIDE 16

The Strategy pattern favors Encapsulation over Extension

l Instead of changing the behavior implemented within a

derived class by extending from a parent class, we encapsulate behaviors into a class as instance attributes, which can be varied.

l The Strategy pattern lets us vary and change behavioral

algorithms independently of the clients that use the behaviors.

slide-17
SLIDE 17

A good Design Pattern has also solved a larger conceptual issue:

To make a program easy to maintain, we always want to strive for

1.

High cohesion

2.

Low coupling

17

slide-18
SLIDE 18

Coupling: How closely two or more classes are related

Does changing code in one class require changes in another class??

l If “yes”, then it has high coupling (bad) l Changing swim or quack behaviors does not require

changes to the Duck class (low coupling)

18

slide-19
SLIDE 19

Other design principles benefitting from the Strategy Pattern

l Decreases coupling, increases cohesion l The behavior of the Duck is not coupled to the Duck –

behaviors are implemented separately.

l Like all Design Patterns, the Strategy pattern allows

us to vary a part of the system (swim and quack behavior) independently of other parts

slide-20
SLIDE 20

Are there disadvantages?

l Yes: the implementation of the Strategy Pattern is

somewhat more sophisticated than using simple inheritance

l All design patterns usually exhibit this type of tradeoff.

20

slide-21
SLIDE 21

Other good design principles we visited

l Code to the most restrictive level of access modification that

is possible in a given context:

i.

Use public for constants and methods; never for

  • attributes. On methods: only on those you want to

support for public consumption

ii.

Use /*package*/ if cooperating classes in the same package need access to attributes or special methods

iii.

Use protected to allow derived classes in any package access to members

iv.

Use private to completely guard members from view

  • utside the defining class