This post has been more than 6 years since it was last updated.
This book of Dustin Boswell and Trevor Foucher focuses simple and practical techniques for writing better code which you can apply every time you write code. The authors introduces the key ideas:
i. Code should be easy to understand.
ii. Code should be written to minimize the time it would take for someone else to understand it.
Using easy-to-digest code examples from different languages, each chapter dives into a different aspect of coding and demonstrates how you can make your code easy to understand:
I. Simplify naming, commenting and formatting with tips that apply for every line of code
II. Refine your program's loops, logic and variables to reduce complexity and confusion
III. Attack problems at the function level, such as reorganizing blocks of code to do one task at a time.
IV. Write effective test code that is thorough and concise, as well as readable.
I. Simplify naming, formatting and commenting
1. Simplify naming
1.1. Pack information into your names
Whether you’re naming a variable, a function, or a class, a lot of the same principles apply. We like to think of a name as a tiny comment. Even though there isn’t much room, you can convey a lot of information by choosing a good name.
KEY IDEA: Pack information into your names.
1.2. Choosing specific words
KEY IDEA: It’s better to be clear and precise than to be cute.
Use FetchPage() or DownloadPage() instead of GetPage() or Height(), NumNodes(), or MemoryBytes() instead of Size().
Finding More “Colorful” Words: deliver, dispatch, announce, distribute, route for send; search, extract, locate, recover for find; launch, create, begin, open for start; create, set up, build, generate, compose, add, new for make.
1.3. Avoiding generic names (or knowing when to use them)
KEY IDEA: Pick a name that describes the entity’s value or purpose.
The name retval doesn’t pack much information. Instead, use a name that describes the variable’s value. The name tmp should be used only in cases when being short-lived and temporary is the most important fact about that variable. If you’re going to use a generic name like tmp, it, or retval, have a good reason for doing so.
1.4. Using concrete names instead of abstract names
For example, suppose you have an internal method named ServerCanStart(), which tests whether the server can listen on a given TCP/IP port. The name ServerCanStart() is somewhat abstract, though. A more concrete name would be CanListenOnPort(). This name directly describes what the method will do.
1.5. Attaching extra information to a name, by using a suffix or prefix
• Using Values with Units
Start(int delay ) delay → delay_secs
CreateCache(int size ) size → size_mb
ThrottleDownload(float limit) limit → max_kbps
Rotate(float angle) angle → degrees_cw
• Encoding Other Important Attributes
password → plaintext_password
comment → unescaped_comment
html → html_utf8
data → data_urlenc
1.6. Deciding how long a name should be
Shorter Names Are Okay for Shorter Scope
Typing Long Names—Not a Problem Anymore
- Type the first few characters of the name.
- Trigger the word-completion command
- If the completed word is not correct, keep triggering the command until the correct name appears.
1.7. Acronyms and Abbreviations
Our rule of thumb is: would a new teammate understand what the name means? If so, then it’s probably okay.
1.8. Throwing Out Unneeded Words
• Using name formatting to pack extra information
1.9. Names That Can’t Be Misconstructed
The best names are ones that can’t be misconstructed—the person reading your code will understand it the way you meant it, and no other way. Unfortunately, a lot of English words are ambiguous when it comes to programming, such as filter, length, and limit. Before you decide on a name, play devil’s advocate and imagine how your name might be misunderstood. The best names are resistant to misinterpretation. When it comes to defining an upper or lower limit for a value, max_ and min_ are good prefixes to use. For inclusive ranges, first and last are good. For inclusive/exclusive ranges, begin and end are best because they’re the most idiomatic. When naming a boolean, use words like is and has to make it clear that it’s a boolean. Avoid negated terms (e.g., disable_ssl). Beware of users’ expectations about certain words. For example, users may expect get() or size() to be lightweight methods.
2. Simplify formatting
Everyone prefers to read code that’s aesthetically pleasing. By “formatting” your code in a consistent, meaningful way, you make it easier and faster to read. Here are specific techniques we discussed:
• If multiple blocks of code are doing similar things, try to give them the same silhouette.
• Aligning parts of the code into “columns” can make code easy to skim through.
• If code mentions A, B, and C in one place, don’t say B, C, and A in another. Pick a meaningful order and stick with it.
• Use empty lines to break apart large blocks into logical “paragraphs.”
3. Simplify comment
3.1. Knowing What to Comment
The purpose of a comment is to help the reader know what the writer knew when writing the code. This whole chapter is about realizing all the not-so-obvious nuggets of information you have about the code and writing those down. What not to comment:
• Facts that can be quickly derived from the code itself.
• “Crutch comments” that make up for bad code (such as a bad function name)—fix the code instead.
Thoughts you should be recording include:
• Insights about why code is one way and not another (“director commentary”).
• Flaws in your code, by using markers like TODO: or XXX:.
• The “story” for how a constant got its value. Put yourself in the reader’s shoes:
• Anticipate which parts of your code will make readers say “Huh?” and comment those.
• Document any surprising behavior an average reader wouldn’t expect.
• Use “big picture” comments at the file/class level to explain how all the pieces fit together.
• Summarize blocks of code with comments so that the reader doesn’t get lost in the details.
3.2. Making Comments Precise and Compact
This chapter is about writing comments that pack as much information into as small a space as possible. Here are the specific tips:
• Avoid pronouns like “it” and “this” when they can refer to multiple things.
• Describe a function’s behavior with as much precision as is practical.
• Illustrate your comments with carefully chosen input/output examples.
• State the high-level intent of your code, rather than the obvious details.
• Use inline comments (e.g., Function(/* arg = */ ... ) ) to explain mysterious function arguments.
• Keep your comments brief by using words that pack a lot of meaning. (Continues)
All Rights Reserved