I find I tend to design class structures where several subclasses have nearly identical functionality, but one piece of it is different. So I write nearly all the code in the abstract class, and then create several subclasses to do the one different thing. Does this pattern have a name? Is this the best way for this sort of scenario?
Option 1:
public interface TaxCalc {
String calcTaxes();
}
public abstract class AbstractTaxCalc implements TaxCalc {
// most constructors and fields are here
public double calcTaxes(UserFinancials data) {
// code
double diffNumber = getNumber(data);
// more code
}
abstract protected double getNumber(UserFinancials data);
protected double initialTaxes(double grossIncome) {
// code
return initialNumber;
}
}
public class SimpleTaxCalc extends AbstractCalc {
protected double getNumber(UserFinancials data) {
double temp = intialCalc(data.getGrossIncome());
// do other stuff
return temp;
}
}
public class FancyTaxCalc extends AbstractTaxCalc {
protected double getNumber(UserFinancials data) {
int temp = initialCalc(data.getGrossIncome());
// Do fancier math
return temp;
}
}
Option 2:
This version is more like the Strategy pattern, and should be able to do essentially the same sorts of tasks.
public class TaxCalcImpl implements TaxCalc {
private final TaxMath worker;
public DummyImpl(TaxMath worker) {
this.worker = worker;
}
public double calcTaxes(UserFinancials data) {
// code
double analyzedDouble = initialNumber;
int diffNumber = worker.getNumber(data, initialNumber);
// more code
}
protected int initialTaxes(double grossIncome) {
// code
return initialNumber;
}
}
public interface TaxMath {
double getNumber(UserFinancials data, double initial);
}
Then I could do:
TaxCalc dum = new TaxCalcImpl(new TaxMath() {
@Override
public double getNumber(UserFinancials data, double initial) {
double temp = data.getGrossIncome();
// do math
return temp;
});
And I could make specific implementations of TaxMath for things I use a lot, or I could make a stateless singleton for certain kinds of workers I use a lot.
So the question I'm asking is: Which of these patterns is superior, when, and why? Or, alternately, is there an even better third option?