Blastasia,Inc. a software company, providing solutions globally    Welcome to Blastasia.com Home Contact Us Sitemap FAQ Inquiry Form Blastasia,Inc. a software company, providing solutions globally
Blastasia,a world class I.T company      TRANSFORMING BUSINESS USING I.T.   
 
Blastasia,Inc. a software company, providing solutions globally Contact Us
 
 
 
Featured Solutions
    Strategy Design Pattern Implementation in .Net Development
 
And, here is another Tax Calculator concrete strategy implementation for another country (Singapore) :
   

public class SingaporeTaxCalculationStrategy : TaxCalculationStrategyBase
{
// Default constructor
public SingaporeTaxCalculationStrategy()
{
}

// Singapore may use tax calculation
// formula different from Japan
public override void CalculateTax()
{
base.orderInfo.TaxAmount =
base.orderInfo.OrderAmount * 10 / 100;
}
}

  We also make use of a factory to give us a specific Tax Calculator.
  Below is one version of the factory
  This class is the point of change when we try to add more calculators.
  This version, though, requires code compilation.
   

public class TaxCalculatorFactory
{
// Context objects uses this static method
// to create a specific tax calculator.
public static TaxCalculationStrategyBase
CreateTaxCalculator()
{
TaxCalculationStrategyBase calculator = null;

// We can retrieve a tax calculator name by using
// an application configuration file.
string calculatorName =
System.Configuration.ConfigurationSettings.AppSettings
["TaxCalculator"];

// We can add appropriate case statements
// to new calculators.
switch (calculatorName)
{
case "Japan":
calculator = new JapanTaxCalculationStrategy();
break;
case "Singapore":
calculator =
new SingaporeTaxCalculationStrategy();
break;
// Add more case statements here.
// case "Philippine":
// calculator =
// new PhilippineTaxCalculationStrategy();
// break;
}

return calculator;
}
}

  Below is another version of a factory.
  We can use reflection to instantiate the type of the calculator based on a configuration file.
 
This way, we only change the configuration file with no code compilation steps needed. The configuration file entry includes the full name of the class that will be instantiated.
   

public class TaxCalculatorFactory
{
public static TaxCalculationStrategyBase
CreateTaxCalculator()
{
// We assume the calculator class is located in
// the same assembly as the client.
// But we can easily load it from any assembly.
Assembly assembly = Assembly.GetExecutingAssembly();

// App.config: ["TaxCalculatorName"] values -
// "TaxCalculators.SingaporeTaxCalculatorStrategy"
string className =
System.Configuration.ConfigurationSettings.AppSettings
["TaxCalculatorName"];

// Use reflection to create an instance.
// Make sure that we cast the result of the
// CreateInstance method.
TaxCalculationStrategyBase calculator;
calculator =
(TaxCalculationStrategyBase)
assembly.CreateInstance(className);

return calculator;
}
}

  Here is the context class that uses the tax calculators:
   

public class OrderInfo
{
// Default Constructor
public OrderInfo()
{
}

// Context class contains or knows only
// the abstract class but has no knowledge
// of any concrete strategy classes.
protected TaxCalculationStrategyBase calculator;

// Provides a method to set a strategy
public void SetTaxCalculationStrategy
(TaxCalculationStrategyBase calculator)
{
this.calculator = calculator;
}

// Client can call this method for tax computation.
public void CalculateTax()
{
// Use the factory to create calculator instance.
this.calculator =
TaxCalculatorFactory.CreateTaxCalculator();

// Set the context of the strategy.
// This type of assignment is often called
// dependency injection.
calculator.SetTaxableInfo(this);

// This effectively sets the TaxAmount property.
calculator.CalculateTax();
}

// Other properties of the context class.
private int orderNo;
public int OrderNo
{
get
{
return orderNo;
}
set
{
orderNo = value;
}
}

private double orderAmount;
public double OrderAmount
{
get
{
return orderAmount;
}
set
{
orderAmount = value;
}
}

private double taxAmount;

// This method will be called by the concrete strategy
// using dependency injection
// or otherwise also termed "inversion of control"
public double TaxAmount
{
get
{
return taxAmount;
}
set
{
taxAmount = value;
}
}

public double TotalAmount
{
get
{
return orderAmount + taxAmount;
}
}

  We can use a client with the following code:
   

public partial class OrderForm : Form
{
public OrderForm()
{
InitializeComponent();
}

private void calculateButton_Click
(object sender, EventArgs e)
{

// Instantiate the context object
OrderInfo orderInfo = new OrderInfo();

// Assign properties
orderInfo.OrderNo = 9999;
orderInfo.OrderAmount =
double.Parse(this.orderAmountTextBox.Text);

// Call tax calculation
orderInfo.CalculateTax();

// Show results.
this.lblOrderAmount.Text =
orderInfo.OrderAmount.ToString();
this.lblTaxAmount.Text =
orderInfo.TaxAmount.ToString();

}
}

  Several things to note here :
 
The context class (OrdeInfo) does not have to know which specific tax calculator it is using. It only knows the base abstract class (TaxCalculationStrategyBase). The factory takes care of the creation of the specific calculator based on the configuration file.
 
 
The client class (OrderForm) does not have to know any tax calculators at all. The tax calculation procedure is encapsulated inside the context class (OrderInfo)
 
  If we want to use a specific calculator, we simply change the configuration file
 
If we want to create another tax calculator for another country, for example, Philippine taxation, we simple derived from the base abstract class (TaxCalculationStrategyBase) and code inside the specific tax calculation implementation.
 
 
In conclusion, the strategy design pattern allows us to encapsulate an algorithm that varies into its own classes. This way we avoid code complexity inside the context class.
   
  References:
 

* Design Patterns Elements of Reusable Object Oriented Software by Gamma, Helm, Johnson, Vlissides

   
  For more information on this solution please email at contactus@blastasia.com
       
     
Back
 
   
 
   Solutions
 
    On-Line Inquiry
Tinette T. Arzadon
  (A.V.P. Business Development)
John Fajardo
  (Client Service Manager)
Meynard Aquino
  (Client Service Manager)
 
 
 
Home   :   Technology   :   Industries   :   Library   :   Partners   :   Clients   :   Dedicated Developer   :   Blastasia.us    :   Terms    :   Policies   :   Sitemap   :   Contact Us
    Copyright© 2008 Blastasia, Inc. All Rights Reserved