Why parallel architecture



Design Patterns: Template Method, Strategy, State, Bridge

|[HFDP, Ch. 8] Say we have two classes whose code looks similar, but isn’t identical. |Outline for Lecture 25 |

|We can duplicate the code, but change it where changes are needed. Is this a good | |

|idea? If you copy it, then you have to keep making changes to both copies any time |I. The Template Method pattern |

|you need to fix a bug. |II. Template Method vs. Strategy |

| |III. State vs. Strategy |

| |IV. Bridge |

Template Method pattern is a way of abstracting similar behavior in various classes and duplicating only the code that differs.

Here’s the example given in the text (p. 282):

|Coffee |Tea |

|void prepareRecipe() { |void prepareRecipe() { |

|boilWater(); |boilWater(); |

|brewCoffeeGrinds(); |steepTeaBag(); |

|pourInCup(); |pourInCup(); |

|addSugarAndMilk(); |addLemon(); |

|} |} |

Do you see the similarity? How might you avoid code duplication? Try to think of more than one way, and submit your answer here.

How should we write the code? Fill in the blanks here.

public abstract class HotBeverage {

final void prepareRecipe() {

boilWater();

brew();

pourInCup();

addCondiments();

}

What other declarations do we need in this class?

void boilWater() {

System.out.println("Boiling water …");

}

void pourInCup() {

System.out.println("Pouring …");

}

abstract void brew();

abstract void addCondiments();

}

What methods do the Coffee and Tea classes need to implement?

brew(); and addCondiments();

Now, let’s draw the class diagram, like it says in the book …

This is the Template Method pattern. Which method in it is a “template method”?

prepareRecipe(), because it serves as a template for an algorithm

Now, let’s write up the pattern definition like we have done for other patterns before.

Template Method

Intent: Capture common parts of an algorithm in a single code sequence.

Problem:

Solution:

Implementation:

Can you think of other examples of Template Method?

One of the main pitfalls in Template Method is that sometimes processes are almost the same, but not exactly. Certain steps need to be performed in some cases, but not in others.

For example, in the coffee case, a customer may not want sugar and milk.

What’s the best way to address this? Hook methods, which are declared in the abstract class, but given an empty implementation.

Our code now becomes …

public abstract class CaffeineBeverage {

final void prepareRecipe() {

boilWater();

brew();

pourInCup();

if condimentsWanted() addCondiments();

}

boolean condimentsWanted() { return true; }

}

The hook method condimentsWanted() is given a default implementation, which can be overridden by subclasses.

Template Method helps avoid the pitfall of “dependency rot.” This means that high-level components (methods of the abstract class) “depend on” low-level components, as well as vice versa.

In this context, what does it mean to “depend on”? To be called by

Why would this be bad to have high-level components depend on low-level components?

The dependency-inversion principle says,

Depend on abstractions. Do not depend on concrete classes.

What example of the dependency-inversion principle did we see in the last lecture?

The case where to create a figure, the class that created the figure tested for what kind of figure needed to be created.

To prevent dependency inversion, we apply the Hollywood principle: Don’t call us, we’ll call you!

How can this be realized in the Template Method pattern? The abstract class calls methods of its subclasses, not vice versa.

How can we prevent the subclass methods from calling methods of the abstract class? Declare them private, if they’re not abstract or hook methods.

One commentator goes even further. He says that multiple layers of Template Methods are inherently prone to the yo-yo effect. What do you think?

Template Method vs. Strategy

Recall the Strategy pattern from Lecture 13.

In this case, you need to choose an algorithm for a task depending on some “parameter” of the situation.

For example, consider quadrature (numerical integration) again. Each time you calculate the area of a region, you need to know what the function is that you are calculating the region underneath.

The definition of Strategy from HFDP is,

The Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

Let’s provide a definition of Strategy in the format that we have used before.

Strategy

Intent: To decouple algorithms from the objects that use them.

Problem:

Solution:

Implementation:

What’s different about the two patterns? See pp. 308—09 of HFDP.

• TM defines the outline of an algorithm & lets subclasses fill in mis





Strategy vs. State

[HFDP, “§”10.10] Hmmm … that’s interesting. Strategy lets objects appear to change class. Isn’t that what State does?

How can we tell the difference between Strategy and State?









Bridge

[HFDP, §14.1] Now, let’s look at the class diagram for the State pattern (for example, at ).

Note that the Context object holds a reference to an abstract class. This is the abstract class from which the concrete states are derived.

It turns out that the same structure is valuable for implementing drivers. What’s a driver?

Drivers are generally used by various applications. Consider a printer driver, for example. There is a driver for a particular printer for each OS. Many different applications can use that printer, providing that the right driver is present.

This is an example of the bridge pattern. We have various abstractions (the applications) and various implementations (the drivers). If the applications aren’t in a hierarchy, the class diagram for Bridge is exactly the same as the class diagram for State.

But often, the abstractions are in a hierarchy. HFDP gives the example of televisions and remotes. TVs have behavior in common, and so do remotes. If they’re “universal remotes,” they can be used by lots of different kinds of TVs.

This leads to the UML diagram on p. 613 of HFDP, or view it online.

What are the advantages of Bridge?



OK, we just told you the right way to handle this problem. What would be the wrong way? Can you imagine using a lot more subclasses?

So one way of looking at Bridge is that it avoids unnecessary subclassing. Let’s describe the pattern.

Bridge

Intent: To decouple interfaces from the implementations that use them.

Problem:

Solution:

Implementation:

Can you think of other examples of Bridge?

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download