Which design pattern - calculations based on many input parameters?

Go To StackoverFlow.com

3

I am designing an inventory system. Each inventory item's taxes need to be calculated based on many conditions (State, County, etc, etc). The rules of calculations change as well over period of time. So I was thinking of the Strategy Pattern but I do not have an extensive experience in making design descions.

What other questions should I be asing my self?

My Inventory Item can be of a different type, so the wiki page on strategy pattern says:

The behaviours of a class should not be inhereted, instead they should be encapsulated using interfaces.

How does this affect my case?

2012-04-04 20:10
by dexter


4

The behaviours of a class should not be inhereted, instead they should be encapsulated using interfaces.

This means that instead of subclassing your Inventory item for each and every possible tax calculation, you should encapsulate the calculation algorithm behind an interface and then use encapsulation inside your Inventory class that points to the correct Strategy object.

This saves you a lot of work since you don't have to declare a new Inventory subclass each time you have a new calculation.

The following implementation uses inheritance:

abstract class InventoryBase
{
   protected abstract Money CalculateTax();
}

class InventoryTaxA : InventoryBase
{
   protected override Money CalculateTax()
   {
      // Calculation A
   }
}

class InventoryTaxB : InventoryBase
{
   protected override Money CalculateTax()
   {
      // Calculation B
   }
}

But the strategy pattern would look like:

class Inventory
{
   public Inventory(ITaxCalculationStrategy taxCalculationStrategy)
   {
      TaxCalculationStrategy = taxCalculationStrategy;
   }

   protected override Money CalculateTax()
   {
       return TaxCalculationStrategy.Calculate(this);
   }
}

So, strategy is definitely a nice solution for abstracting your tax calculations. If the rules of which calculation apply at a certain time are different and can change I would also use a Factory for creating the correct Strategy object.

2012-04-04 20:24
by Wouter de Kort


3

I think you need to step up a bit on your design and look at how the process of tax calculation happens, when it's done, by whom, for whom and where it gets recorded. Whoever is responsible for that would take as input an inventory item and would then need to find out what's the applicable tax calculation method given the item (and the context) attributes. That process might involve asking a tax calculation policy object for a suitable method. Very high level it would be like this:

tax_calculation_method = tax_policy.get_method_for(inventory_item)
tax_value = tax_calculation_method.calculate_for(inventory_item)
tax_account.record_tax(tax_value, for_item: inventory_item)

So, the strategy pattern can play a fundamental part in isolating the process above from the specifics of the calculation method and from the specifics of finding a suitable method given an inventory item (so it's already being used twice), but it's just an implementation detail of the overall design. Many other patterns may apply, from factories to repositories, or specifications and composites for complex criteria, to name a few.

To get inspired, take a look at some accounting analysis patterns (pdf).

2012-04-04 20:38
by Jordão
Ads