1. If you want to add a feature to a program and find that the code lacks good structure and is not easy to change, refactor the program to make it easier to add the feature, and then add the feature.

Refactoring is the art of modifying a program in small steps. If you make a mistake, it’s easy to spot it.

Any fool can write code that a computer can understand. A good programmer is one who can write code that humans can easily understand.

4. The test of good code is how easily people can change it.

5. If you look at how most programmers spend their time, they spend a very small percentage of their time writing code. Some time is spent deciding what to do next, some time is spent on design, but the most time is spent on debugging. I’m sure every reader can remember spending hours debugging code — often all night. Every programmer can tell a story about a bug that took a whole day (or more) to fix. Fixing bugs is usually quick, but finding them is a nightmare. Fixing one bug often leads to another, only to notice it much later. At that point, you spend a lot of time trying to locate the problem.

6. When you feel the need to write comments, try refactoring first, trying to make all comments redundant.

7. A set of tests is a powerful bug detector that can greatly reduce the time needed to find bugs.

8. Run tests frequently. For the code you’re working on, the corresponding tests should run at least every few minutes, and all tests should run at least once a day.

9. Don’t write tests just because tests can’t catch all bugs, because tests can catch most bugs.

10. Whenever you receive a bug report, write a unit test to expose the bug.

Programming is, to a large extent, a conversation with the computer: I write code to tell the computer what to do, and its response is to act precisely on my instructions. In a nutshell, what I do is fill the gap between “what I want it to do” and “what I tell it to do.” Programming is all about saying exactly what I want. However, don’t forget that there are other readers of the source code besides computers: in a few months another programmer may try to read my code and make some changes to it. It’s easy to forget about this reader, but he’s the one that matters. What does it matter if the computer takes a few more clock cycles to compile? If a programmer spends a week fixing a piece of code, that’s a big deal — if he understands my code, the change could have taken an hour.

Good design must be completed before you start programming, because once you start writing code, the design will only gradually corrupt. Refactoring changes the picture.

Dirty code must be refactored, but beautiful code also needs a lot of refactoring.

14. The sole purpose of refactoring is to allow us to develop faster and create more value with less work.

15. Some people try to justify refactoring with moral arguments like “clean code” and “good engineering practices,” which I think is a trap. The point of refactoring is not to polish up the codebase, but purely economic. We refactor because it makes us faster — faster to add features, faster to fix bugs. Be sure to keep this in mind at all times and reinforce it when communicating with others. Refactoring should always be driven by economic interests. The more programmers, managers, and customers understand this, the more often the “good design” curve will appear.

16. Most people will feel that having a large inheritance is a good thing, but from a programmer’s point of view, it’s different. Legacy code is often complex, undertested, and, crucially, written (shudder) by someone else.

17. If a team wants to refactor, each team member needs to be able to refactor when needed without interfering with the work of others. This is why I encourage continuous integration: with CI, each member’s refactoring can be quickly shared with the rest of the team, so you don’t have to call an interface and then delete it. If a refactoring affects someone else’s work, we’ll know soon enough. Self-tested code is also a key part of continuous integration, so these three practices — self-tested code, continuous integration, and refactoring — have strong synergies with each other.

18. A well-constructed program helps this optimization approach in two ways. First, it gives me more time to make performance tweaks, because with well-constructed code in hand, I can add features more quickly and spend more time on performance issues (accurate measurement ensures that I spend that time in the right places). Second, with well-constructed programs, I have a finer granularity for performance analysis. The measurement tool takes me into smaller pieces of code, and performance tuning is easier. Because the code is clearer, I can better understand my choices and know which adjustments are critical.

19. Run tests frequently. For the code you’re working on, the corresponding tests should run at least every few minutes, and all tests should run at least once a day.

Is a test set good enough? The best measure is subjective. Ask yourself: If someone introduced a bug into your code, how confident are you that it will be found by the test set? This confidence is hard to quantify, and blind confidence shouldn’t count, but the whole goal of self-testing code is to help you gain it. If I refactor the code and see all the tests turn green, I can be confident that NO additional bugs have been introduced, and I can happily say that I have a good enough set of tests.

The above sentence is from Refactoring to Improve the design of existing Code (paperback edition 2)

By Martin Fowler. Bear Festival. Translated by Lin Congyu

 

The book is an updated version of the classic “Refactoring”, published 20 years later. It clearly reveals the refactoring process, explains how refactoring works and practices, and shows when and where to start digging code for improvement. There are more than 60 possible refactorings, each of which introduces a proven motivation and technique for transforming code. The refactoring guidelines outlined in this book will help developers make small changes to the code one step at a time, thereby reducing risk in the development process. This book is suitable for software developers, project managers, etc., and can also be used as a reference for teachers and students of computer science and related majors in colleges and universities.