Chapter 9: The Strategy Pattern
Code Examples
TOC
TOC
Example
TOP
Switches, etc.
// Handle Tax
switch (myNation) {
case US:
// US Tax rules here
break;
case Canada:
// Canadian Tax rules here
break;
}
// Handle Currency
switch (myNation) {
case US:
// US Currency rules here
break;
case Canada:
// Canadian Currency rules
// here
break;
}
// Handle Date Format
switch (myNation) {
case US:
// use mm/dd/yy format
break;
case Canada:
// use dd/mm/yy format
break;
}
But what happens when there are more variations? For example, suppose I need to add Germany to the list of countries and also add language as a result. Now, the code looks like this:
// Handle Tax
switch (myNation) {
case US:
// US Tax rules here
break;
case Canada:
// Canadian Tax rules here
break;
case Germany:
// Germany Tax rules here
break;
}
// Handle Currency
switch (myNation) {
case US:
// US Currency rules here
break;
case Canada:
// Canadian Currency rules
// here
break;
case Germany:
// Euro Currency rules here
break;
}
// Handle Date Format
switch (myNation) {
case US:
// use mm/dd/yy format
break;
case Canada:
case Germany:
// use dd/mm/yy format
break;
}
// Handle Language
switch (myNation) {
case US:
case Canada:
// use English
break;
case Germany:
// use German
break;
}
This still is not too bad, but notice how the switches are not quite as nice as they used to be. There are now fall-throughs. But then I need to start adding variations within a case. Suddenly, things get bad in a hurry. For example, to add French in Quebec, my code looks like this:
// Handle Language
switch (myNation) {
case Canada:
if (inQuebec) {
// use French
break;
}
case US:
// use English
break;
case Germany:
// use German
break;
}
Step 2: Favor aggregation
Example 9-1: Implementing the Strategy Pattern
TOP
public class TaskController {
public void process () {
// this code is an emulation of a
// processing task controller
// . . .
// figure out which country you are in
CalcTax myTax;
myTax= getTaxRulesForCountry();
SalesOrder mySO= new SalesOrder();
mySO.process(myTax);
}
private CalcTax getTaxRulesForCountry() {
// In real life, get the tax rules based on
// country you are in. You may have the
// logic here or you may have it in a
// configuration file
// Here, just return a USTax so this
// will compile.
return new USTax();
}
}
public class SalesOrder {
public void process (CalcTax taxToUse) {
long itemNumber= 0;
double price= 0;
// given the tax object to use
// . . .
// calculate tax
double tax = taxToUse.taxAmount(itemNumber,price);
}
}
public abstract class CalcTax {
abstract public double taxAmount(long itemSold,double price);
}
public class CanTax extends CalcTax {
public double taxAmount(long itemSold,double price) {
// in real life, figure out tax according to
// the rules in Canada and return it
// here, return 0 so this will compile
return 0.0;
}
}
public class USTax extends CalcTax {
public double taxAmount(long itemSold,double price) {
// in real life, figure out tax according to
// the rules in the US and return it
// here, return 0 so this will compile
return 0.0;
}
}