As we all know, splitting the logic in a function or method into smaller methods is great practice for both unit testing purposes and reader friendly code.
Lets look at an example:
public boolean doAlotOfStuff(List<String> stuffAs, List<String> stuffBs) {
List<String> stuffCs = ArrayList<String>();
for (String stuffA : stuffAs) {
for (String stuffB : stuffBs) {
String stuffC = stuffA + stuffB;
stuffCs.add(stuffC);
}
}
}
This looks still readable? yes, but kinda hard, now imagine these are not simple string combination but added with substrings and calling database to store.(And I wont waste time to create a complex logic example)
But how can u unit test this? test cases will involve putting in different arrays of stuffAs and stuffBs, which in the method has a heavy logic embedded
Now, how about we split the work load to different methods and make the code more clean?
public boolean doAlotOfStuff(List<String> stuffAs, List<String> stuffBs) {
List<String> stuffCs = ArrayList<String>();
for (String stuffA : stuffAs) {
List<String> appendedStuffBs = appendStuffBsWithStuffA(stuffA, stuffBs);
}
}
public List<String> appendStuffBsWithStuffA(String stuffA, List<String> stuffBs){
List<String> appendedStuff;
for (String stuffB : stuffBs) {
String stuffC = stuffA + stuffB;
appendedStuff.add(stuffC);
}
return appendedStuff;
}
simpler? now we have split the logic off into the method appendStuffBswithStuffA for a certain string combination.
We can now unit test the first method with a mock that will mock the behavior of appendStuffBswithStuffA and not to worry about it.
Most of us would see the need to split another step further if the logic inside the loop is heavy:
But in our case, splitting another level down would be over doing it, and gets confusing for another programmer to read the code later.
So in conclusion, ALWAYS ALWAYS split multi level logic into simpler readable, testable methods. One will see great benefit as the project progresses.