Goodbye Simplicity I’m Object Obsessed – Example
Suppose we had the following (utterly) simplistic requirement:
@Test public void politiciansDontNeedToPayTax() { whenIncomeIs(10000).verify(POLITICIANS).pay(0); } @Test public void residingAliensGetAwayByPayingLittleTax() { whenIncomeIs(10000).verify(ALIENS).pay(1000); } @Test public void richPeopleArePunishedWithHighestTax() { whenIncomeIs(10000).verify(RICH_PEOPLE).pay(3000); } |
where:
TaxPayer RICH_PEOPLE = new RichPeople(); TaxPayer ALIENS = new ResidingAliens(); TaxPayer POLITICIANS = new Politicians(); |
To fullfil this requirement, we’ve the following code:
Parent Class:
public abstract class TaxPayer { protected abstract double getTaxPercentage(); public double calculateTaxAmount(final long income) { if (getTaxPercentage() == 0) return 0; return income * getTaxPercentage() / 100.0; } } |
Each child class:
public class Politicians extends TaxPayer { private double taxPercentage = 0; @Override protected double getTaxPercentage() { return taxPercentage; } } |
public class RichPeople extends TaxPayer { private final double taxPercentage = 30; @Override protected double getTaxPercentage() { return taxPercentage; } } |
public class ResidingAliens extends TaxPayer { private final double taxPercentage = 10; @Override protected double getTaxPercentage() { return taxPercentage; } } |
One would wonder what good are these child classes? Feels like a class explosion. Sure enough! This is the pathetic state of Object Oriented programming in many organizations, esp. the Enterprise software side of the world.
One could have easily used an enum to solve this problem:
public enum TaxPayer { Politicians(0), Aliens(.1), RichPeople(.3); private double taxPercentage; private TaxPayer(double taxPercentage) { this.taxPercentage = taxPercentage; } public double calculateTaxAmount(final long income) { return income * taxPercentage; } } |