Yesterday I found some nice video from some IT conference about removing if statements from code. I saw a very nice example of refactoring. I am curious what do you think about it, especially what weak points do you see in such approach.
1) We have a class with very "nice" method:
public int inferCategoryID(Component c) { if(c.hasOneChannel() && c.hasValidCertificate() && c.isTested() && c.frequentlyUsed()) { return 24; } if(c.hasOneChannel() && c.hasValidCertificate() && !c.isTested() && c.frequentlyUsed()) { return 95; } if(c.hasOneChannel() && !c.hasValidCertificate() && c.isTested() && c.frequentlyUsed()) { return 221; } if(c.hasTwoChannels() && c.hasValidCertificate() && c.isTested() && c.frequentlyUsed()) { return 2004; } if(c.hasTwoChannels() && c.hasValidCertificate() && !c.isTested() && c.frequentlyUsed()) { return 20044; } if(c.hasTwoChannels() && c.hasValidCertificate() && !c.isTested() && !c.frequentlyUsed()) { return 2003; } // etc... } As you can see all conditions are mutually exclusive.
2) The idea was, to create a separate class for each condition - under a common interface:
interface CategoryIDCondition { public boolean isTrue(Component c); public int getID(); } class Cat24Condition implements CategoryIDCondition { public boolean isTrue(Component c){ return c.hasOneChannel() && c.hasValidCertificate() && c.isTested() && c.frequentlyUsed(); } public int getID(){ return 24; } } // etc...
3) Usage example:
public int inferCategoryID(Component c) { List<CategoryIDCondition> conditions = new ArrayList<>(); conditions.add(new Cat24Condition); conditions.add(new Cat95Condition); // etc... (btw. not a good place for list init but never mind...) for (CategoryIDCondition cond : conditions) { if(cond.isTrue(c)){ return cond.getID(); } } } What weak points do you see in such approach apart from that, that conditions have to be mutually exclusive, or have to be added to conditions list in a very specific order? Would you decide to use such strategy in your code?
Componentavailable? I think there-in lies your problem. Shouldn't this logic be right in that class? \$\endgroup\$