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?
Component
available? I think there-in lies your problem. Shouldn't this logic be right in that class? \$\endgroup\$