SIMPLICITY
When we are explaining something unfamiliar to someone we speak as simply as we can. Likewise, when we write code we should write it as simply as we can. Keep in mind that someone will be reading that code later, trying to understand what it does and how it does it. We should strive to keep our code as clear and intent-revealing as possible.
Do the Simplest Thing
So how do we keep our code clear? One way is to use simple algorithms as much as possible. Always assume that the simplest way of doing something is the best. If it proves not to be, we can always change it. One of the phrases heard a lot in the eXtreme Programing world is "What is The Simplest Thing That Could Possibly Work?"
"What," you may ask, "does that mean?" Well, consider this simple test:
public void testEmptyList() { MovieList emptyList = new MovieList(); assertEquals(0, emptyList.size()); }
In order to get this test to pass once it is compiling, we do the simplest thing that could possibly work. Specifically:
public int size() { return 0; }
When we do this we know that the size() method is too simple, but at this point we don't know what it should be, and returning zero is the simplest thing that makes the test pass. We will have to generalize this method later, but not until we write tests for non-empty list behavior.
Keep It Simple by Refactoring
Another way to keep code simple and intent-revealing is to change unclear code so that it is clear. This is one way that refactoring is used. Chapter 2 has a more in-depth discussion of this incredibly important topic.
There are many refactorings that deal with increasing the intent-revealing quality of a piece of code. While it could be argued that most of Fowler's refactorings make code clearer, we only consider a handful here. See [15] and [16] for more information on these and the remainder. The simplest of these include renaming classes, methods, variables, etc. Some of the more complex intent-revealing refactorings are explained next.
-
Introduce Explaining Variable If we have a complex expression, we take parts of it and put those intermediate values in temporary variables with names that explain the purpose of the subexpression.
-
Extract Method If we have a method that is getting overly complex, we make part of it into a separate method. This is also useful if we see common code in multiple methods: we extract the common part (possibly parameterized) into a separate method that can be called by multiple clients.
-
Extract Class If we have a class that is doing too much or that has multiple responsibilities, we extract related responsibilities into separate classes.
-
Replace Temp with Query Rather than computing a value and storing it in a temporary variable, we extract the computation into a method that returns the result, and call that instead.
-
Split Temporary Variable If we find a case where a temporary variable is reused, we create a new temporary variable for each use.
-
Remove Assignments to Parameters If we find code that assigns to a parameter, we use a temporary variable instead.