More on this book
Community
Kindle Notes & Highlights
Read between
August 24 - September 9, 2019
Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure.
“Improving the design after it has been written.
A good design comes first, and the coding comes second.
Here’s how to get the most from this book without reading all of it.
If you are writing a program that you don’t expect to change, then cut and paste is fine. If the program is long lived and likely to change, then cut and paste is a menace.
When you find you have to add a feature to a program, and the program’s code is not structured in a convenient way to add the feature, first refactor the program to make it easy to add the feature, then add the feature.
Whenever I do refactoring, the first step is always the same. I need to build a solid set of tests for that section of code.
Before you start refactoring, check that you have a solid suite of tests. These tests must be self-checking.
Refactoring changes the programs in small steps. If you make a mistake, it is easy to find the bug.
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
It is a bad idea to do a switch based on an attribute of another object. If you must use a switch statement, it should be on your own data, not on someone else’s.
Figure 1.12. Class diagram before moving methods to movie
A movie can change its classification during its lifetime. An object cannot change its class during its lifetime. There is a solution, however, the State pattern [Gang of Four].
you are familiar with the Gang of Four patterns, you may wonder, “Is this a state, or is it a strategy?”
To introduce the state pattern I will use three refactorings. First I’ll move the type code behavior into the state pattern with Replace Type Code with State/Strategy (227). Then I can use Move Method (142) to move the switch statement into the price class. Finally I’ll use Replace Conditional with Polymorphism (255) to eliminate the switch statement.
The most important lesson from this example is the rhythm of refactoring: test, small change, test, small change, test, small change. It is that rhythm that allows refactoring to move quickly and safely.
Refactoring (noun): a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.
Refactor (verb): to restructure software by applying a series of refactorings without changing its observable behavior.
When you refactor, you make a point of not adding function; you only restructure the code. You don’t add any tests (unless you find a case you missed earlier); you only change tests when you absolutely need to in order to cope with a change in an interface.
don’t want to proclaim refactoring as the cure for all software ills. It is no “silver bullet.”
“I’m not a great programmer; I’m just a good programmer with great habits.”
The first time you do something, you just do it. The second time you do something similar, you wince at the duplication, but you do the duplicate thing anyway. The third time you do something similar, you refactor.
Whenever I have to think to understand what the code is doing, I ask myself if I can refactor the code to make that understanding more immediately apparent.
Code reviews help spread knowledge through a development team. Reviews help more experienced developers pass knowledge to less experienced people.
Programs have two kinds of value: what they can do for you today and what they can do for you tomorrow.
Every time you break one thing into two pieces, you have more things to manage.
Don’t publish interfaces prematurely. Modify your code ownership policies to smooth refactoring.
If it stinks, change it.
A heuristic we follow is that whenever we feel the need to comment something, we write a method instead.
If you only have a few cases that affect a single method, and you don’t expect them to change, then polymorphism is overkill. In this case Replace Parameter with Explicit Methods (285) is a good option.
You get it when people say, “Oh, I think we need the ability to do this kind of thing someday” and thus want all sorts of hooks and special cases to handle things that aren’t required.
When you feel the need to write a comment, first try to refactor the code so that any comment becomes superfluous.
Fixing the bug is usually pretty quick, but finding it is a nightmare.
Make sure all tests are fully automatic and that they check their own results.
A suite of tests is a powerful bug detector that decapitates the time it takes to find bugs.
Functional tests typically treat the whole system as a black box as much as possible.
When you get a bug report, start by writing a unit test that exposes the bug.
Think of the boundary conditions under which things might go wrong and concentrate your tests there.
