I have a (php) program, which must change yearly. This program calculates tax for every year and there are sometime changes in requirements. First, the user fills their incomes, expenses, etc. Then clicks the download button, which creates an xml file for him.
The Download class use Calculator classes to calculate the full tax results.
Lest say i have 5 types of calculators. (one calculator per tax report section)
CalcTaxBase, CalcTaxFree, CalcEtc...
In the 1st year i created the classes CalcTaxBase13 ans so on.
The taxBase calculator have methods r1(), r2() and r3().
Next year came, nothing changed in taxBase so i created CalcTaxBase14 extended from previos year class.
(there is a year attribute which i use to load some parameters, of course changing yearly)
Then in 2015 i had to overload r3() and add r4() to CalcTaxBase15
I created this hierarchy because tought this way i can reuse the non changing methods from previous years and implement only the changes or new methods but i have more problem with this.
- Now it is a nightmare to quickly find, in which year i have the most recent r3(). With code navigation it is better but i have to jump over every time a need to find something.
- I have the same hierarchy of Download classes, because of yearly changes. I had to pass taxBase13.r1() to taxFree13.r1 in 2013 but 2 years later i had to pass the taxBase.r4() to some other calculator, and this is done in the download class. The download class feeds my calculators with inputs and then uses their results to make an xml.
- I can't use type definitions in my Download class methods, because the (let's say Download.configureTaxBase($taxBase)) needs TaxBase13 but the Download14.configureTaxBase($taxBase) need this for year 14. (i made it with docblocks now) As i see i can't refer to interfaces because in the new years i will have new methods.
Hope it makes some sense for you. Can someone please suggest me some better design?