Clean Code - notes
Notes from the book by R.C. Martin
Summary of thoughts
This is a long detailed book. Some of the examples could be better. But the general concepts here are very good and this is a must read. I think it is a bonus that it is so long, because it treats the good ideas with the detail they deserve.
3. Functions
Function Arguments
ideal number of function arguements for a function is zero
Flag Arguments
passing a boolean into a function is truly a terrible practise
we should have split the function into two:
renderForSuite()
andrenderForSingleTest()
No Side Effects
Command Query Separation
Functions should either do something or answer something … not both
Extract Try/Catch Blocks
extract the bodies of the
try
andcatch
blocks out into functions of their own
4. Comments
The proper use of comments is to compensate for our failure to express ourself in code
Good Comments
the only truly good comment is the comment you found a way not to write
Don’t Use a Comment When You Can Use a Function or a Variable
Consider the following stretch of code:
// does the module from the global list <mod> depends on the // subsystem we are part of? if (module.getDependedSubsystems().contains(subSysMod.getSubSystem()))
This could be rephrased without the comment as
ArrayList moduleDependencies = smodule.getDependedSubsystems() String ourSubSystem = subSysMod.getSubSystem() if (moduleDependencies.contains(ourSubSystem()))
5. Formatting
Team Rules
6. Objects and Data Structures
Train Wrecks
final String outputDir = ctx.getOptions()getScratchDir().getAbsolutePath()
Active Record
treat the Active Record as a data structure
8. Boundaries
Exploring and Learing Boundaries
may be in our interest to write tests for the third-party code we use
Learning Tests are Better Than Free
Learning tests verify that the third-party packages we are using work the way we expect them to
Clean Boundaries
good software accomodate change without huge investments and rework
9. Unit Tests
- tests should have one and only one assert statement
- test a single concept in each test function
F.I.R.S.T.
- Fast They should run quickly
- Independent Tests should not depend on each other
- Repeatable Tests should be repeatable in any environment
- Self-Validation Tests should … either … pass or fail
- Timely unit tests should be written just before the production code
10. Classes
Class Organisation
put the private utilities called by a public function itself
Encapsulation
for us, tests rule
The single Responsibility Principle
one reason to change
11. Systems
it is a myth that we can get systems “right the first time”
12. Emergence
run all the tests
17. Smells and Heuristics
General
- G1: Multiple languages in one source file
- G10: Vertical separation variables and functions should be defined close to where they are used
- G13: Artificial Coupling things that don’t depend upon each other should not be artificially coupled
- G23: Prefer Polymorphism to If/Else or Switch/Case
- G24: Follow Standard Conventions
- G25: Replace Magic Numbers with Named Constants
- G28: Encapsulate Conditionals >
if (shouldBeDeleted(timer))
is preferrable toif (timer.hasExpired() && !timer.isRecurrent())
- G29: Avoid Negative Conditionals >
if (buffer.shouldCompact())
is preferrable toif (!buffer.shouldNotCompact())
- G30: Functions Shouls Do One Thing
- G31: Hidden Temporal Couplings
- G33: Encapsulate Boundary Conditions >
if (level + 1 < tags.length())
is preferrable toif (nextLevel < tags.length())
Names
- N1: Choose Descriptive Names
Tests
- T9: Tests Should Be Fast