Whilst these smells are different animals, I grouped them together in a single post because the driving forces behind them and their symptoms are fairly similar. In both cases, your code becomes difficult and arduous to read, modification becomes a challenge, development time skyrockets and tests fail frequently. So, with all the negative aspects, why do we keep doing it?
Long Methods are a throwback to when invoking a subroutine added a significant overhead to an application. A lot of legacy code will still feature huge, monolithic “do everything” methods which are all but impossible to read and modify. For efficiency, it was better to keep everything together. These days, most compilers optimise out the majority of these overheads, so its not really a big issue.
Another cause of Long Methods is temp variables. In order to access the temp variable, the accessor needs to be in the same scope (the method). This can be remedied with some aggressive refactoring.
Remedying Long Methods
A long method is caused by:
- Requiring access to temp variables
- Trying to do too much without delegating
So our solution is:
- Replace those temp variables with a method with the same result
- Delegate some of the method’s responsibilities to a new method
In both cases, these solutions have the following shared advantages:
- The new methods are accessible from other places in your code. We reduce duplication and make life easier later on
- The new methods can be named appropriately, increasing readibility of our code and reducing the need for comments
- When profiling our application, we get a much more fine grained understanding of where our bottlenecks are
Replacing Temp Variables
The following steps are required to replace a temp variable:
- Ensure the temp variable is assigned to exactly once (Mark it as final and see if your compiler throws an error)
- Ensure the assignment has no side-effects
- Extract the assignment to an appropriately named method
- Anywhere that variable is referenced, reference the method instead
- Delete the temp variable
Most IDE’s provide an automated “Extract Method” feature to do this for you. Select a set of candidate lines and use it. I recommend you do all your temp variable removal first, as this cuts down the number of parameters passed to the extracted method!
A large class is a sign of a design flaw in your application. Usually, it indicates your object is trying to assume too many responsibilities. The Single Responsibility Principle states that:
“A class should have a single responsibility, and that responsibility should be entirely encapsulated by the class”
If your class has gotten too big, chances are your class has assumed more than a single responsibility and violated this principle.
Remedying Large Classes
As this usually occurs because you violated the Single Responsibility Principle, the first step is to get back in line! Check your class carefully and see if it is doing anything outside of its own problem area. If it is, create a new class to deal with this functionality.
In cases where you have lots of instance variables which aren’t always used, consider extracting these into a data class or subclass and referencing that instead
And finally, remove duplication! See my post here for advice on doing this