Modern object-oriented languages tend to support the concept of “reflection”. Reflection lets you inspect an object and find out its methods and invoke them dynamically. If you’re building extensible frameworks where you’re handling objects where their type might not be known until runtime, it can be very useful. On the other hand, if you’re using a strongly typed language and find yourself in this situation frequently… you’re probably doing something wrong.
For that reason, when Adam encounters calls to method.invoke()
in Java programs, he gets suspicious. So, when he saw this:
Method method = generator.getClass().getMethod(methodName, null);
customerListList = (ArrayList) method.invoke(generator, null);
Adam knew he had to investigate. First, he looked up how the methodName
variable was being populated. A few lines up, he saw:
String methodName = "getCustomerListFor"+ alphaBet.trim().toUpperCase();
And then, he checked the generator class:
public ArrayList getCustomerListForA() {...}
public ArrayList getCustomerListForB() {...}
public ArrayList getCustomerListForC() {...}
public ArrayList getCustomerListForD() {...}
There were twenty six copy-pasted versions of the getCustomerList
method, where the only difference was that each had a hard-coded string which defined how to filter the data set.
When Adam asked the developer why they didn’t simply use a parameter, the developer replied. “I didn’t want to have to write a switch statement.”