Refactoring
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
What is refactoring?
Refactoring is the name given to changing the structure of our code whilst keeping its behaviour the same. Re-structuring our code, but without breaking anything.
The name comes from factoring, which comes from algebra. Factoring is the basic idea of splitting something up into smaller parts. Refactoring is simply ‘doing it again’.
I am always refactoring.
I’ll refactor as part of the TDD process, as is standard. I will write a failing test, add the simplest production code to make it pass, then refactor.
When faced with new code that’s hard to understand, I’ll refactor it first. That way, I capture any insights I get and preserve this hard-won understanding in the code.
That’s why refactoring is useful. But how do we do it?
Martin Fowler’s book Refactoring is the reference on this subject. The first edition is all Java-based and the one I recommend for Java devs. The second edition uses JavaScript ES6 with class support for the examples. It’s okay, but not as direct for us Java developers.
Here are the refactoring steps I use all the time - and why.
Rename Method, Rename Variable
1 class User {
2 private final String text ;
3
4 public User( String name ) {
5 this.text = name ;
6 }
7
8 public void printout() {
9 System.out.println("Welcome back, " + text);
10 }
11 }
This User class will print out ‘Welcome back, Alan’ after creating the object passing in the name Alan.
The name is stored in a field called ‘text’. Hmm. It is text - but that’s not really telling me what that field is used for. It is being used to store the User’s name that we want to put into the welcome message.
The fix is to use Refactor > Rename of that field. Call it ‘name’.
In the same vein, method ‘printout()’ isn’t very helpful in understanding the code, either. Yes, the method will print something out. We can read that. But that isn’t what it is doing, that’s how. We want our methods to explain why they are there and what their outcome is.
We can use Refactor > Rename on the method name to give it a descriptive name. Let’s choose ‘welcome()’. This better explains what is being done.
1 class User {
2 private final String name ;
3
4 public User( String name ) {
5 this.name = name ;
6 }
7
8 public void welcome() {
9 System.out.println("Welcome back, " + name);
10 }
11 }
These two refactorings - changing the name of a field or method - are the ones I use all the time. Literally. To the point where I no longer stress out about thinking up ‘the best’ names. I just code, come up with a first stab at a name, then come back and refactor it when I get a better idea.
I find my brain works like that. Something happens in the background as I am working away. I’ll get a better insight a little later.
Prefer IDE tools over manual changes
Your IDE if it is IntelliJ, Eclipse, NetBeans or VS Code will automate this process. As Java is a strongly typed language, the IDE can find all references to that field text and change them all in one go. Same for the method and all its call sites.
Use the tools. It is much faster. You will introduce fewer bugs.
Extract Method
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Change Method Signature
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Extract Parameter Object
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Can we refactor anything into anything else?
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.