unit 18 strategy summary prepared by kirk scott 1

77
Unit 18 Strategy Summary prepared by Kirk Scott 1

Upload: damian-butler

Post on 13-Jan-2016

222 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Unit 18 Strategy Summary prepared by Kirk Scott 1

1

Unit 18Strategy

Summary prepared by Kirk Scott

Page 2: Unit 18 Strategy Summary prepared by Kirk Scott 1

2

Design Patterns in JavaChapter 23

Strategy

Summary prepared by Kirk Scott

Page 3: Unit 18 Strategy Summary prepared by Kirk Scott 1

3

The Introduction Before the Introduction

• In general, a single strategy might be thought of as an algorithm or an operation

• In the context of the Strategy design pattern, the idea is that there are multiple approaches to doing something, depending on certain conditions or context

• The Strategy design pattern, then, depends on picking the approach or picking the strategy

Page 4: Unit 18 Strategy Summary prepared by Kirk Scott 1

4

• When there is more than one way to go about doing something, complexity can result

• Not only are there the different implementations to consider

• There is also the code that is devoted to making the choice of which strategy to use

Page 5: Unit 18 Strategy Summary prepared by Kirk Scott 1

5

• The purpose of the Strategy design pattern is to separate the implementations of different strategies from each other

• It also separates the code for picking the strategy from the strategy implementations

• The pattern defines a single interface for all strategies

Page 6: Unit 18 Strategy Summary prepared by Kirk Scott 1

6

• The separate strategies are implemented with a method of the same name in each of the classes implementing the interface

• Which strategy is used will depend on what kind of object the method implementing the strategy is called on

• The intent of the pattern is realized through an interface and depends on polymorphism and dynamic binding

Page 7: Unit 18 Strategy Summary prepared by Kirk Scott 1

7

Book Definition of Pattern

• Book definition:• The intent of Strategy is to encapsulate

alternative approaches, or strategies, in separate classes that each implement a common operation.

Page 8: Unit 18 Strategy Summary prepared by Kirk Scott 1

8

Modeling Strategies

• Like with the previous chapters, and others, the book illustrates the Strategy design pattern in the following way:

• It develops an example with multiple strategies that doesn’t use the Strategy design pattern

• It then refactors the example using the Strategy design pattern

Page 9: Unit 18 Strategy Summary prepared by Kirk Scott 1

9

Example Scenario

• When a potential customer calls in, interested in buying fireworks, there is software which will make a recommendation or suggestion

• There are several different ways a recommendation can be made:

• Either a particular firework is being promoted, or two pieces of software, Rel8 or LikeMyStuff can make a recommendation, or a default option can be chosen

Page 10: Unit 18 Strategy Summary prepared by Kirk Scott 1

10

• Rel8 relies on a customer’s already being registered

• During registration the customer specifies preferences in entertainment and fireworks

• Rel8 makes a suggestion based on the similarity of the customer to other customers (presumably suggesting something that similar customers have tended to buy)

• If the customer isn’t registered, Rel8 can’t be used

Page 11: Unit 18 Strategy Summary prepared by Kirk Scott 1

11

• LikeMyStuff doesn’t rely on pre-registration, but it does rely on customer information

• The idea is that it will make a recommendation based on a profile of recent purchases by the customer

• If not enough data can be obtained to form the profile, then LikeMyStuff can’t be used

Page 12: Unit 18 Strategy Summary prepared by Kirk Scott 1

12

• This is the default:• If none of the previous options applies, then a

firework is suggested at random

Page 13: Unit 18 Strategy Summary prepared by Kirk Scott 1

13

UML for the Scenario

• The UML diagram on the following overhead shows the classes involved in the design as described so far

• Appendix D on UML clarifies the notation:• “Use a dashed arrow between classes to show

a dependency that does not use an object reference. For example, the Customer class relies on a static method from the LikeMyStuff recommendation engine.”

Page 14: Unit 18 Strategy Summary prepared by Kirk Scott 1

14

Page 15: Unit 18 Strategy Summary prepared by Kirk Scott 1

15

The getRecommended() Method

• Viewing the scenario from the top down, what you have is this:

• The Customer class has a getRecommended() method in it

• This method consists of if/else code which chooses one of the strategies, whether to do a promotion, or to use Rel8, LikeMyStuff, or the default

Page 16: Unit 18 Strategy Summary prepared by Kirk Scott 1

16

Doing a Promotion

• If there is a promotion underway, the first part of the logic of getRecommended() deals with that case

• The logic for doing a promotion consists of looking up the contents of a file named strategy.dat in a directory named config

• If there is such a file, its contents should look something like this: promote=JSquirrel

Page 17: Unit 18 Strategy Summary prepared by Kirk Scott 1

17

• The basic idea is that if the data file is not empty, the firework it contains is returned

• If its contents come up null you go on to the next option

• Also, if the file read doesn’t work, you don’t do anything in the catch block, you just continue on to the other options

Page 18: Unit 18 Strategy Summary prepared by Kirk Scott 1

18

Using Rel8

• The Rel8 class has a method advise(), so getRecommended() wraps a call to that method if that strategy is selected

• The call looks like this:• if(isRegistered())• return (Firework) Rel8.advise(this);

• “this” is the customer, and Rel8 relies entirely on the information contained in the registered customer object

Page 19: Unit 18 Strategy Summary prepared by Kirk Scott 1

19

Using LikeMyStuff

• The LikeMyStuff class has a suggest() method, so getRecommended() wraps a call to that method if that strategy is selected

• The call looks like this:• if(spendingSince(cal.getTime()) > 1000)• return (Firework) LikeMyStuff.suggest(this);

• “this” is the customer, and LikeMyStuff relies on a database of recent purchases by that customer, which is accessed by the call to spendingSince() on the customer

Page 20: Unit 18 Strategy Summary prepared by Kirk Scott 1

20

• The Firework class has a getRandom() method, so if all else fails, getRecommended() wraps a call to that method

• The code for getRecommended() is shown on the following overheads

• It is a collection of if statements.• It is unfortunate that it is not organized as a

sequence of if/else if’s.

Page 21: Unit 18 Strategy Summary prepared by Kirk Scott 1

21

The Code for getRecommended()• public Firework getRecommended()• {• // if promoting a particular firework, return it• try• {• Properties p = new Properties();•

p.load(ClassLoader.getSystemResourceAsStream(“config/strategy.dat”));• String promotedName = p.getProperty(“promote”);• if(promotedName != null)• {• Firework f = Firework.lookup(promotedName);• if(f != null)• return f;• }

Page 22: Unit 18 Strategy Summary prepared by Kirk Scott 1

22

• catch(Exception ignored)• {• // If resource is missing or it failed to load,• // fall through to the next approach.• }• // if registered, compare to other customers• if(isRegistered())• {• return (Firework) Rel8.advise(this);• }

Page 23: Unit 18 Strategy Summary prepared by Kirk Scott 1

23

• // check spending over the last year• Calendar cal = Calendar.getInstance();• cal.add(Calendar.YEAR, -1);• if(spendingSince(cal.getTime()) > 1000)• return (Firework) LikeMyStuff.suggest(this);

• // oh well!• return Firework.getRandom();• }

Page 24: Unit 18 Strategy Summary prepared by Kirk Scott 1

24

What’s Wrong with the Initial Design

• The book identifies two basic problems with the getRecommended() method as given:

• It’s too long• It combines both selecting a strategy and

executing it

Page 25: Unit 18 Strategy Summary prepared by Kirk Scott 1

25

• This is actually one of the high points of the book

• It explains that you know that the method is too long because you need to put comments in it

• “Short methods are easy to understand, seldom need explanation…”

Page 26: Unit 18 Strategy Summary prepared by Kirk Scott 1

26

• Finally, what every student always knew: Comments are bad…

• More accurately, you might facetiously say that code which requires comments is bad.

• The book doesn’t say that putting a comment at the beginning for the whole method is bad.

• A useful observation might be that a method should be short and sweet enough that it doesn’t need internal commenting.

Page 27: Unit 18 Strategy Summary prepared by Kirk Scott 1

27

Refactoring to the Strategy Pattern

• Applying the Strategy design pattern involves three things:

• 1. Creating an interface that defines the strategic operation

• 2. Writing classes that represent each strategy and implement the interface

• 3. Refactoring the code to select and use an instance of the right strategy class

Page 28: Unit 18 Strategy Summary prepared by Kirk Scott 1

28

The Interface

• 1. The interface will be named Advisor• The interface requires that an implementing

class have a method named recommend()• The recommend() method will take a

customer as a parameter• It will return a firework• A UML diagram of the interface is given on the

next overhead

Page 29: Unit 18 Strategy Summary prepared by Kirk Scott 1

29

Page 30: Unit 18 Strategy Summary prepared by Kirk Scott 1

30

The Implementing Classes

• 2. The next step is to create the classes that represent the different strategies and implement the interface

• The book essentially presents this information as part of the following challenge

Page 31: Unit 18 Strategy Summary prepared by Kirk Scott 1

31

• Challenge 23.1• Fill in the class diagram in Figure 23.3, which

shows the recommendation logic refactored into a collection of strategy classes.

• Comment mode on:• What they want is mindlessly simple• That will be clear when you see the answer

Page 32: Unit 18 Strategy Summary prepared by Kirk Scott 1

32

Page 33: Unit 18 Strategy Summary prepared by Kirk Scott 1

33

• Solution 23.1• Figure B.24 shows one solution.

Page 34: Unit 18 Strategy Summary prepared by Kirk Scott 1

34

Page 35: Unit 18 Strategy Summary prepared by Kirk Scott 1

35

• The PromotionAdvisor and RandomAdvisor class names should be self-explanatory

• GroupAdvisor refers to the use of Rel8• ItemAdvisor refers to the use of LikeMyStuff• The implementations of the recommend()

method for these classes will wrap a call to the static methods of Rel8 and LikeMyStuff

• An expanded UML diagram for these two classes is given on the next overhead

Page 36: Unit 18 Strategy Summary prepared by Kirk Scott 1

36

Page 37: Unit 18 Strategy Summary prepared by Kirk Scott 1

37

Making Instances of the Implementing Classes

• An interface can’t define static methods• An interface defines what the book calls

“object methods”—methods that are called on objects

• Instances of GroupAdvisor and ItemAdvisor, the classes that implement the interface, are needed in order to call the methods defined in the interface an implemented in them

Page 38: Unit 18 Strategy Summary prepared by Kirk Scott 1

38

• Only one instance each of GroupAdvisor and ItemAdvisor are needed

• In the refactored design, these instances will be static objects in the Customer class

Page 39: Unit 18 Strategy Summary prepared by Kirk Scott 1

39

Code for the recommend() Method in the GroupAdvisor Class

• This is what the recommend() method looks like in the GroupAdvisor class:

• public Firework recommend(Customer c)• {• return (Firework) Rel8.advise(c);• }

• By means of a wrapped call, the implementation of the method translates from the advise() interface of Rel8 to the recommend() interface of Advisor

Page 40: Unit 18 Strategy Summary prepared by Kirk Scott 1

40

Code for the recommend() Method in the ItemAdvisor Class

• The code for the recommend() method in the ItemAdvisor class is analogous.

• The book doesn’t give it and it doesn’t even bother to give it as a challenge.

• It should be straightforward to write that method.

Page 41: Unit 18 Strategy Summary prepared by Kirk Scott 1

41

• Challenge 23.2• In addition to Strategy, what pattern appears

in the GroupAdvisor and ItemAdvisor classes?

Page 42: Unit 18 Strategy Summary prepared by Kirk Scott 1

42

• Solution 23.2• The GroupAdvisor and ItemAdvisor classes are

instances of Adapter, providing the interface a client expects, using the services of a class with a different interface.

• Comment mode on:• This wasn’t so hard—describing the wrapping

of the call as “translating” kind of gave it away

Page 43: Unit 18 Strategy Summary prepared by Kirk Scott 1

43

Code for the recommend() Method in the PromotionAdvisor Class

• A PromotionAdvisor class is also needed, with a recommend() method

• Most of the logic of the original code is moved into the constructor for the new class

• If a promotion is on, then the promoted instance variable of the class is initialized

Page 44: Unit 18 Strategy Summary prepared by Kirk Scott 1

44

• In addition to the recommend() method, there is a hasItem() method which can be called to see whether a promoted item is available

• Overall, the code is a bit messy because of the class loader logic and the try/catch blocks

• The details of this technique will not be covered since they are extraneous to the design pattern

• The code is shown on the following overheads

Page 45: Unit 18 Strategy Summary prepared by Kirk Scott 1

45

• public class PromotionAdvisor implements Advisor • {• private Firework promoted;• public PromotionAdvisor() • {• try • {• Properties p = new Properties();•

p.load(ClassLoader.getSystemResourceAsStream("config/strategy.dat"));• String promotedFireworkName = p.getProperty("promote");• if (promotedFireworkName != null) • promoted = Firework.lookup(promotedFireworkName);• } • catch (Exception ignored) • {• // Resource not found or failed to load• promoted = null;• }• }

Page 46: Unit 18 Strategy Summary prepared by Kirk Scott 1

46

• public boolean hasItem() • {• return promoted != null;• }• public Firework recommend(Customer c) • {• return promoted;• }• }

Page 47: Unit 18 Strategy Summary prepared by Kirk Scott 1

47

Code for the recommend() Method in the RandomAdvisor Class

• The RandomAdvisor class is simple• Its code is shown on the following overhead

Page 48: Unit 18 Strategy Summary prepared by Kirk Scott 1

48

• public class RandomAdvisor implements Advisor • {• public Firework recommend(Customer c) • {• return Firework.getRandom();• }• }

Page 49: Unit 18 Strategy Summary prepared by Kirk Scott 1

49

Refactoring the Customer Class to Use the Interface

• In order to make use of the recommend() method, a single instance of each of the advisor classes may be needed

• The new customer class, Customer2, has these lines of code in it at the top:

• private static PromotionAdvisor promotionAdvisor =• new PromotionAdvisor();

• private static GroupAdvisor groupAdvisor =• new GroupAdvisor();

• private static ItemAdvisor itemAdvisor =• new ItemAdvisor();

• private static RandomAdvisor randomAdvisor =• new RandomAdvisor();

Page 50: Unit 18 Strategy Summary prepared by Kirk Scott 1

50

• Customer2 also contains a method named getAdvisor() for picking which kind of advisor to use

• This code is organized around a sequence of if/else if statements

• In other words, the logic for picking the advisor replaces the earlier code which called different strategies directly

Page 51: Unit 18 Strategy Summary prepared by Kirk Scott 1

51

• The book calls the approach used in the code lazy-initialization

• It’s not lazy construction because one instance of each kind of advisor has already been created

• The point is that the value of the advisor instance variable for a customer is only set at the time that you try to acquire an advisor

• The code is shown on the following overhead

Page 52: Unit 18 Strategy Summary prepared by Kirk Scott 1

52

• private Advisor getAdvisor() • {• if (advisor == null) • {• if (promotionAdvisor.hasItem())• advisor = promotionAdvisor;• else if (isRegistered())• advisor = groupAdvisor;• else if (isBigSpender())• advisor = itemAdvisor;• else• advisor = randomAdvisor;• }• return advisor;• }

Page 53: Unit 18 Strategy Summary prepared by Kirk Scott 1

53

• Challenge 23.3• Write the new code for

Customer.getRecommended().• Comment mode on:• In other words, write the code for the new

getRecommended() method in the Customer2 class• This code should rely on the advisor for the

customer, and a call to the recommend() method on that advisor

Page 54: Unit 18 Strategy Summary prepared by Kirk Scott 1

54

• Solution 23.3• Your code should look something like:• public Firework getRecommended()• {• return getAdvisor().recommend(this);• }

Page 55: Unit 18 Strategy Summary prepared by Kirk Scott 1

55

• This is where it becomes blindingly apparent that some of the code in the application is simplified by the design.

• Dynamic binding determines which version of recommend() will be used depending on the type of advisor that was initialized earlier.

Page 56: Unit 18 Strategy Summary prepared by Kirk Scott 1

56

Comparing Strategy and State

• Consider the Strategy design pattern example• The redesign ended with a recommend()

method implemented in several different advisor classes

• The recommend() method is called in the customer getRecommended() method

• Which version of recommend() is called depends on polymorphism, the type of the object it is called on

Page 57: Unit 18 Strategy Summary prepared by Kirk Scott 1

57

• Recall the State design pattern example• It ended with a touch() method implemented

in several different state classes• Which version of touch() was used depended

on the object that it was called on• It is possible to argue that there is little

difference between the State and Strategy design patterns

Page 58: Unit 18 Strategy Summary prepared by Kirk Scott 1

58

• At the macro level, structurally, at least, this is the case

• If you compared the UML diagrams of the relationships between classes in the two patterns, they would be very similar

• This has also been apparent with some of the patterns already considered

Page 59: Unit 18 Strategy Summary prepared by Kirk Scott 1

59

• The book argues that the critical difference is that states and strategies have different intents

• The difference isn’t just one of intent• It’s clear from the problem domains that there

is a difference between transitioning between states of doors and choosing among fireworks to recommend

Page 60: Unit 18 Strategy Summary prepared by Kirk Scott 1

60

• The point of the touch() method was that calling it in one state caused you to enter another

• Calling the recommend() method on a GroupAdvisor object doesn’t somehow send the application into a state where the current ItemAdvisor is no longer applicable

• At the micro level, this is apparent in the design and code

• The strategy pattern does not do the same thing that the state pattern does

Page 61: Unit 18 Strategy Summary prepared by Kirk Scott 1

61

• With strategy, the application may choose among different strategies based on various conditions

• With state, the client may take an action, but it doesn’t explicitly choose a state

• The logic of the states themselves control the transition from one to another

• The book concludes that in spite of their structural similarity, State and Strategy are different patterns

Page 62: Unit 18 Strategy Summary prepared by Kirk Scott 1

62

Comparing Strategy and Template Method

• Recall the first Template Method design pattern example

• The template was a sort() method in the Arrays or Collections class

• What was stubbed in was the pairwise comparison operation for elements of the data structure

Page 63: Unit 18 Strategy Summary prepared by Kirk Scott 1

63

• The authors state that you might argue that changing the pairwise comparison step changes the strategy of sorting

• They illustrate this idea by suggesting that sorting rockets by price rather than by thrust would support a different marketing strategy

• Observe that the claim about strategy in this argument is about something in the problem domain, marketing, not in the code writing

Page 64: Unit 18 Strategy Summary prepared by Kirk Scott 1

64

• Challenge 23.4• Provide an argument that the Arrays.sort() method

provides an example of Template Method or that it is an example of Strategy.

• Comment mode on:• It’s clear that the book thinks sorting is an example

of template, not strategy, since sorting was covered in the template unit.

• I agree with its reasoning, as presented in the second of the following arguments

Page 65: Unit 18 Strategy Summary prepared by Kirk Scott 1

65

• Solution 23.4• Is a reusable sort routine an example of

Template Method or of Strategy?• [See the following overheads.]

Page 66: Unit 18 Strategy Summary prepared by Kirk Scott 1

66

An Argument that Sorting is an Example of the Strategy Design Pattern

• Template Method, according to the original Design Patterns book, lets “subclasses” redefine certain steps of an algorithm.

• But the Collections.sort() method doesn’t work with subclasses; it uses a Comparator instance.

• Each instance of Comparator provides a new method and thus a new algorithm and a new strategy.

• The sort() method is a good example of Strategy.

Page 67: Unit 18 Strategy Summary prepared by Kirk Scott 1

67

An Argument that Sorting is an Example of the Template Design Pattern

• There are many sorting algorithms, but Collections.sort() uses only one (QuickSort).

• Changing the algorithm would mean changing to, say, a heap sort or a bubble sort.

• The intent of Strategy is to let you plug in different algorithms.

• That doesn’t happen here.• The intent of Template Method is to let you plug a

step into an algorithm.• That is precisely how the sort() method works.

Page 68: Unit 18 Strategy Summary prepared by Kirk Scott 1

68

• The book’s argument is good—but maybe not entirely clear.

• The point is that at the macro level, a choice among strategies would mean a choice between different sorting algorithms

• At the micro level, choosing between pairwise comparisons doesn’t change the overall strategy

• It is an example of applying the template pattern

Page 69: Unit 18 Strategy Summary prepared by Kirk Scott 1

69

Another Example

• As usual, there is another example on the course Web page

• It involves cups and seeds• It doesn’t illustrate anything new about the

pattern, so it will not be covered in class• If you would like practice with the pattern you

can work the example as an exercise

Page 70: Unit 18 Strategy Summary prepared by Kirk Scott 1

70

UML for the Pattern

• The UML diagram given earlier is repeated on the following overhead

• It is specific to the fireworks problem, but otherwise it shows what the pattern is about

• It might be possible to make this and other patterns clearer by including sequence diagrams

• It would show how the getRecommended() method makes a call to the recommend() method

Page 71: Unit 18 Strategy Summary prepared by Kirk Scott 1

71

Page 72: Unit 18 Strategy Summary prepared by Kirk Scott 1

72

A UML Diagram for the Pattern from Lasater

• Lasater’s UML diagram is given on the following overhead

• It is useful, as usual, because it uses generic names for the classes in the pattern

• This one is also useful because it shows that you could use an abstract class just as easily as you could use an interface when applying the pattern

Page 73: Unit 18 Strategy Summary prepared by Kirk Scott 1

73

Page 74: Unit 18 Strategy Summary prepared by Kirk Scott 1

74

Summary

• Multiple strategies may appear in a single method

• This can be an unwieldy design• A solution is to implement each separate

strategy as a method of the same name in different classes

• The individual implementations will be simpler

Page 75: Unit 18 Strategy Summary prepared by Kirk Scott 1

75

• The original design would have logic to pick one of the strategies

• The new design would also contain such logic somewhere, but at least it is separated from the implementations of the strategies

• The new logic will be based on which of the strategy classes is constructed

• It would be reasonable to hold the strategy object as a reference in a client class

Page 76: Unit 18 Strategy Summary prepared by Kirk Scott 1

76

• Then at the appropriate time, this object has the strategy method called on it

• In other words, once the object choice is made, the method choice is accomplished by polymorphism

• The result of this kind of design is individual pieces of code that are smaller, simpler, and unified in purpose

• Overall, the design should be clearer, with different strategies implemented in different classes

Page 77: Unit 18 Strategy Summary prepared by Kirk Scott 1

77

The End