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; } }