Design Problem - Low Coupling

Design Problem - Low Coupling

Old forum URL: forums.lhotka.net/forums/t/4893.aspx


tna55 posted on Sunday, May 25, 2008

Hello friends,

I have learned a lot from these forums and CSLA. I have another query that will help me and hopefuly will others may learn from it as well.

I am working on a payroll system with a lot of calculations. The calculations access database at various places to get tax limits and rates etc. The calculations also need data from various person's records.

I want to keep the calculations totally seperate from any sort of data access.  One of the reason to keep things seperate is that the company wishes to sell the calculation part seperately.

I am thinking to have something like TaxCalculator and TaxCalculatorManager. The manager will provide whatever data is neccessary to calculator. Another way may be to pass ITaxDataProvider to the TaxCalculator. ITaxDataProvider can then have methods to get data.  

I am not sure whether these solutions are good. I would really appreciate some input from everyone and Rocky specially. How to we keep business logic/calculations seperate from data access?

Tahir

smiley riley replied on Tuesday, May 27, 2008

Iwill probably get shot here.

Why not create the Tax Caluculations as a standalone usable component/application.

IMHO passing the ITaxDataprovider breaks a number of principles. Much better to define  Data and Behavioural contracts and encapsulate any tax specific data access, or include the required information in the interface and allow it to be passed in as specific tax rate type for example. Ideally the first.

How many tax calculations will you have!! If you have a lot you may benefit from using design patterns such as Strategies, Composites and Factories. e.g.

 

You may have a

AbstractTaxCalculator

{

protected float percentagerate;

CalculateTax( float taxableincome );

}

 

BasicRateCalculator : AbstractTaxCalculator

{

public BasicRateCalculator { percentagerate=20;}

public CalculateTax( float taxableincome ){}

}

 

HighRateCalculator : AbstractTaxCalculator

{

public HighRateCalculator { percentagerate=40;}

public CalculateTax( float taxableincome ){}}

 

//There would be an abstract composite that would define the calculators but this should give you

//an idea of what I am trying to show you.

IncomeTaxCalculator:AbstractTaxCalculator

{

IList<ITaxCalculator> calculators = new.....

public IncomeTaxCalculator

{ calculators.add(new LowRateTaxCalculator) ;  calculators.add(new HighRateTaxCalculator) ;}

public CalculateTax( float taxableincome )

{ foreach ( ICalculator calc in calculators) //add the results of each call retun the tax. obviosuly more too it than this.}}

}

The advantage of this is each individual tax object can be used on its own or in combination with many other tax objects, these calculations can be brought together at runtime using a factory pattern.

Depends on your timescales, and how critical it is that this application be able to operate independently.

Copyright (c) Marimer LLC