The Clean Coder Robert C. Martin
My notes of the book The Clean Coder by Robert C. Martin.
I urge every developer to read this book. The book contains practical explanation on what it means to be a profesionnal developer.
1. Professionalism
“the Boy Scout rule” : check in code cleaner than when you checked it out
- Must be conversant with minimal knowledge:
- Design Patterns
- Design principles
- Methods (scrum, lean, structured design, structured analysis, ..)
- Disciplines (TDD, OOD, continuous integration, ..)
- Artifacts (UML, charts, diagrams, …)
Musicians master their craft not by performing but by practicing The daily job is not practice
The best way to learn is to teach
- Do your due diligence on the business domain
🔑 Key concept:
Treat Software the way a sculptor treats clay, continuously shape and mold it.
2. Saying No
Say no clearly when you can’t say yes
Why is a lot less important than the fact. No Need to provide too much details
“Trying” is a commitment and admitting that you are holding back Trying = extra effort = commit
Don’t try to be a hero
Never accept dropping disciplines
Dropping disciplines creates problems, it NEVER solves them
🔑 Key Concept :
Be clear and honest.
Dont’ try to be a hero.
Never abandon your disciplines.
3. Saying Yes
Commitment Equals:
- Say
- Mean
- Do
- Know how to recognize real commitment
- “Need/Should”, “Hope/Wish”, “Let’s..” Is NOT commitment
- Is only about YOU=, not other
- If the goal depends on someone else, commit only to specific actions you have full control on that bring you closer to the end goal (or commit to finding those specific actions)
If you can’t commit raise a clear RED flag as soon as possible
NEVER drop disciplines
Be honest about your own stamina and reserve
- Explain personal cost and demande your free time if you overtime
Key Concept:
Professionals are not required to say yes to everything that is asked of them.
However, they should work hard to find creative ways to make “yes” possible.
When professionals say yes, they use the language of commitment so there is no doubt about what they’ve promised.
4. Coding
- Coding is a marathon, not a sprint
- Coding is a creative activity. Take care of your personal creative input Creative Input = Creative Output (Read SF ?)
Typing blind
- Typing blind is about confidence Exercise it and learn to sense errors in your typing to build confidence
Focus
- Coding needs concentration and focus. It is a challenging and exhausting activity
- Don’t code if TIRED or DISTRACTED, settle your mind first
Pair and recall context to stay in focus
- You have to juggle competing many factors You code must:
- Work
- Solve the customer problem
- Fit into the existing system
- Be readable by other programmers
The Zone
- DON’T let yourself into the ZONE Makes you loose big picture = bad decision = have to go back = loss of time
- The ZONE is for practicing
Debug
DEBUG TIME = CODING TIME
Reducing debug time is a responsibility. Adopt the right disciplines (TDD)
Hope
Do NOT hope and let others hope Follow your estimates (see chapter X)
DO NOT be tempted to rush and tell your boss you already considered it
Overtime
- Don’t agree to overtime unless:
- you can personally afford it
- it is short term (< 2 weeks or less)
- your boss has a plan if the rush fails
“Done”
- Rationalize “Done”, never think “Done enough” Ask business and testers for acceptance tests
Work with others
- Ask for help and give it Gives new perspective, resets forces and focus, awesome learning
- Seek mentoring from seniors, don’t wait for it
5. Test Driven Development (TDD)
THREE LAWS OF TDD:
- Write a failing unit test before any production code
- Write only part of a unit test if it is sufficient to fail. Not compiling is failing.
- Only write sufficient production code to pass the current failing test
These 3 rules will lock you in 30 sec long cycles.
Unit tests are documents (detailed docs) Lowest-level description of the system’s design
Unit tests force good design (force functions decoupling)
After-the-fact tests are bad because you already know how to solve the problem
6. Practicing
- Performance = Practice
- Practice must be done on your own time
You will get paid for for you practice at your work
Seek diversity in practice User others languages than the ones you regularly use
- Consider Open-Source projects They are the “pro-bono” work lawyers do to challenge themselves and show their skills
Exercises:
KATA: precise choreographed mouvement that simulates one side of a combat Movement and decisions practice : programming KATAs simulates solving problems, the solution is known
- WASA: two-man kata. Aggressor vs defender.
WASA: Programming ping-pong
- Defender writes a unit test
- Aggressor writes code to pass the test and writes a new unit test
- Aggressor and defender exchange roles
The defender can write a unit test for a new problem whenever he chooses and has full control of how the test should be passed (by writing a unit test with any condition to pass inside it)
- RANDORI: free-form combat Like two-man kata but they are more than 2 participants and people take turn to write unit tests and code to pass
Practice Ressources:
http:s//katas/sopftwarecraftmanship.org/
https://codekata.pragprog.com/
“The bowling game”
“Prime factors”
“Word Wrap”
7. Acceptance Testing
Stakeholders and programmers collaboration in order to define a shared definition of done
ALWAYS AUTOMATED
“late precision” principle Should be written as late as possible In agile, written after features enter sprint
Business will write “happy paths” Focus where features have business value
QA will write “unhappy paths” Boundary conditions, exceptions, corner cases
8. Testing Strategies
[!quote] QA
- QA should find nothing
- QA is part of the team, work together
- QA identifies the actual behavior of the system
Automation Pyramid
Unit Tests:
100% coverage true coverage (=asserts behavior)🚀 Run speed: Fast (TDD: constantly ran)
💰 Dev and testing cost: Low
- Way to specify what you will write
- Part of Continuous Integration
Component Tests:
~50% coverage🚀 Run speed: Fast
💰 Dev and testing cost: Low
- Individual components of the system
- Wraps component
- Pass input and gather output
- Acceptance tests of business rules
- Other parts of the application are mocked
- Inside a component testing environnement
Integration Tests:
~20% coverage🚀 Run speed: Slow (periodical runs)
💰 Dev and testing cost: Moderate
- Assemble groups of components
- Test how well they communicate
- “Choreography tests”
- Ensure architectural structure
- Run periodically
- NOT part of Continuous Integration
System Tests:
~10% coverage🚀 Run speed: Slow (periodical runs)
💰 Dev and testing cost: High
- Against entire integrated system
- Does not test business
- Throughput and performance tests
- Written by architects and lead devs
Manual Exploratory Tests:
~5% coverage🚀 Run speed: Very Slow
💰 Testing cost: Very High
- Done by QA
- By hand, no automation, nor script
- Check is system behaves well under human operations
- Goal is to creatively find peculiarities
9. Time Management
- Your responsibility is your project first
Meetings
Accept meetings only if your participation is immediately and significantly necessary to the job you are doing now
Leave a meeting respectfully if:
- it’s bad use of your time,
- it’s boring
- if you can no longer contribute
Stand-up meeting (agile daily):
- 📅Schedule: Every day
- 🚀Goal: Report yesterday’s activity and prepare the day
- 📄Content:
- Each member answers 3 questions:
- What did I do yesterday ?
- What am I doing today ?
- What is in my way ?
- ⏰Time management:
- 20 secondes answer for each question
Sprint planning meeting:
- 📅Schedule: At the start of each sprint
- 🚀Goal: Select backlog for next sprint
- 📄Preparation:
- Estimates should already be done
- Assessment of business value should already be done
- Acceptance/component tests should be done or at least sketched out
- ⏰Time management:
- 5% of total sprint time maximum (for a 40h sprint = 2h meeting)
- If item discussion takes too much time, schedule an other meeting with a subset of the team
Retrospective Meeting:
- 📅Schedule: At the end of each sprint
- 🚀Goal: Discuss what when write or wrong during the sprint and demo to stakeholders
- 📄Preparation:
- Quickly prepare what is going to be demonstrated
- Prepare documents to share if needed
- ⏰Time management:
- Scheduled 45 minutes before the end of the sprint’s last day
- 20 minutes retrospective maximum
- 25 minutes demonstration
Working with others
- If you disagree, express it or you must engage in made choices
- If an argument must be settled, present the arguments in turn and vote
- “Focus-mana” is limited, take time to recharge it Sleep, caffeine, de-focus to re-focus
Personal time management
Pomodoro Technique
- Work and pause in cycles
- Classic pomodoro:
- 4 cycles of 25 minutes work and 5 minutes pause
- Take 30 minutes pause every 4 cycles
- Easy productivity statistics by counting the number of cycles
Common time wasting behaviors
- Priority Inversion:
- ❌Behavior: Avoid the task with the true priority by falsely raising the priority of another task
- ✅Solution: Don’t avoid scary work and keep you tasks priority in check
- Blind alleys:
- ❌Behavior: Vested in a decision you wander down into a technical pathway that leads to nowhere
- ✅Solution: Always keep an open mind into other ideas. Learn to have the skill of quickly realizing you are in a blind alley and the courage to back out.
- Upgradable code:
- ❌Behavior: Don’t act when you see code that you could upgrade
- ✅Solution: Immediately act on code you could upgrade. Understand that the cost will always be bigger later.
10. Estimation
Different definitions
- For business: estimation = commitment
- For developers: estimation = guess /= commitment
- A commitment is a distribution of probabilities
PERT: Program Evaluation and Review Technique
Triviate Analysis:
Input: 3 estimates for the task
- O: Optimisic (<1% occurrence)
- N: Nominal (greatest chance of occurrence)
- P: Pessimistic (<1% occurance)
Output: 2 computed value
\(\mu \text{ : Expected Duration} = {O + 4N + P \over 6}\) \(\sigma \text{ : Standard Deviation} = {P - O \over 6}\) \(\text{ESTIMATE} = {\mu \over \sigma}\) A proper estimation is composed of an **Expected Duration** and a **Standard Deviation**
Set of tasks \(\mu_{set} = {\sum \mu_{task}}\) \(\sigma_{set} = {\sum \sigma_{task}^2}\)
Task Example:
\(\text{Input :} \qquad O = 1 \qquad P = 12 \qquad N = 3\) \(\text{Output :} \qquad \mu = {1 + 4*3 + 12 \over 6} = 4,2 \qquad \sigma = {12 - 1 \over 6} = 1,8\) \(\text{ESTIMATE :} = 4,2 / 1,8\) \(\text{The task will probably take 5 days (4,2)}\) \(\text{But could take 6 or 9 days (+1,8 or +1,8*2)}\)
Set of tasks example:
\(\mu_1 = 4,2 \qquad \mu_2 = 3,5 \qquad \mu_3 = 6,5\) \(\sigma_1 = 4,2 \qquad \sigma_2 = 3,5 \qquad \sigma_3 = 6,5\)
\(\mu_{set} = 4,2 + 3,5 + 6,5 = 14\) \(\sigma_{set} = (1,8^2 + 2,2^2 + 1,3^2)^{1/2} \simeq 3,13\) \(\text{The 3 tasks could probably take 14 days to be completed} (\mu)\) \(\text{But could take 17 or 20 days} (1 \sigma \; or \; 2 \sigma)\)
Nominal estimate techniques
Wideband delphi, “Flying Fingers” or “Planning Poker”:
- Discuss the task
- Blind estimation of each members
- If the estimations are close, take the average
- If there is significant differences in estimation by at least one member iterate with another discussion and vote until ALL estimations are close
Affinity estimation:
- Teams members sort the tasks without showing their estimation nor talking to each other (shared list, usually on board)
- Any card moved n times by any members is set aside for discussion
- Discuss cards and replace until no more movement
- Group tasks in buckets of estimate (traditionally in Fibonacci sequence buckets)
Law of large numbers:
The sum of sub-tasks estimates is a good estimate for the parent task (apply to hard task and large estimates)
Key concepts:
- Don’t commit if you cant
- Provide hard numbers
- Provide probabilistic estimates: Expected completion time and Variance
11. Pressure
The professional developer is =calm and decisive under pressure= As the pressure grows he adheres to his training and disciplines They are the best way to meet the deadlines and commitments that are pressing on him
The best way to stay calm under pressure is to avoid the situations that cause pressure
Business commitments made for us:
We are honor bound to help the business find a way to meet those commitments
We are NOT honor bound to accept the commitments
Be a professional:
Professionals will always help the business find a way to achieve its goals
But professionals do not necessarily accept commitments made for them by the business
Staying Clean:
Professionals realize that “quick and dirty” is on oxymoron. Dirty always means slow !
Disciplines in time of crisis:
- Truly believe in your disciplines
- Choose disciples that you feel confortable following in a crisis.
- Follow your disciplines ALL THE TIME
- They are the BEST WAY to avoid getting into a crisis
- Don’t change your behavior when the crunch comes. Instead follow them even more.
Responds to crisis with more disciplines, not less
This is not the time to question or abandon disciplines.If you follow TDD : Write even more tests that usual If you are a merciless refactor: refactor even more If you keep your functions small: keep them even smaller
In tough times rely on what you already know, your DISCIPLINES
Handling Pressure
Don’t Panic:
- The worst thing you could do is rush !
- Rushing will only drive you deeper in the hole you might be in.
- Instead, slow down. Think the problem through.
Communicate:
If you are in trouble:
- Let your team and superior know that you are in trouble
- Tell them your best plans for getting out of trouble
- Ask them for their input and guidance
Avoid creating surprises. They multiply pressure by ten, make people angry and less rational.
Get Help
- PAIR !
- Offer to pair when you see someone else who is under pressure.
Key Concepts:
- Manage your commitments and the commitments others might make for you
- Follow your disciplines at all times and keep clean
- Stay calm, communicate, follow your disciplines and get help
12. Collaboration
- Teams are most effective when the team members collaborate professionally Being a loner or a recluse on a team is unprofessional
Programmers vs People
- Programmers tend to enjoy mild sensory deprivation and cocoon like immersion of focus
Programmers vs Employers
Pay attention to the ship you are sailing on.
The worst thing a programmer can do is to bury himself in tech while the business is crashing and burning around him Keeping the business afloat is your job too !
- Take time to understand the business
- Talk to users about the software they are using
- Talk to sales and marketing people about the problems and issues they have
- Talk to managers to understand the short and long-term goals of the team
Programmers vs Programmers
The team own the code, not individuals.
Worst symptoms of a dysfunctional team is when each programmer builds a wall around his code and refuses to let other programmers touch it
It is far better to break down all walls of code ownership and have the team own ALL the code
- Work with each other on as much of the system you can
- Learn from each other by working with each other on other parts of the system
Pairing
Two heads are better than one:
Pairing is :
- The most efficient way to solve problems
- The best way to share knowledge with each other
- The best way to review code (the even best way is collaborating in writing it)
All team members should be able to play another position in a pinch
Working alone
Working alone:
You might think that you work better when you work alone
Does that mean that the team works better when you work alone ?
- It is unlikely that you do work better when you work alone
- It is better to collaborate closely with others and to pair with them a large fraction of the time
Key Concept:
Programming is all about working with people
13. Teams and Projects
- It makes no sense to tell a programmer to devote half their time to project A and the rest of their time to project B Different project managers, different business analysts, different programmers, different testers : that NOT a team
The Gelled Team
It take time for a team to form:
- They learn how to collaborate with each other
- They learn each other’s quirks, strengths and weaknesses
A Golden team will:
- Anticipate each other
- Cover for each other
- Demand the best from each other
Team Composition: The ratio of programmers to testers and analysts can vary but 2:1 is a good number
Programmers:
Testers:
Write automated acceptance tests
- Focus: Unhappy paths: failure and boundary (what might go wrong)
Analysts:
Develop the requirements and write automated acceptance tests
- Focus: Happy Paths: business value
A Project Manager:
Tracks the progress of the team and makes sure the team understands the schedules and prioritiesTeam Conscience:
One of the team members may play a part-time role of coach or master and take responsibility for defending the team’s process and disciplines They act as the team conscience when the team is tempted to go off-process because of schedule pressure
Fermentation
- It takes time for a team to work out differences, come to terms with each other, and really gel
- It is ludicrous to break it apart just because a project comes to an end
- It’s best to keep that team together and just keep feeding it projects
Which can first, the Team or the Project ?
It is a foolish approach to form a team around a project Team members need the time to learn to work together A short project or working multiple project for a fraction of the time does not do that
A team that is gelled together can, as a team, change its focus if needed and relocate priorities quickly. Because they know each other and how to work with each other. They will reorganize quickly and easily.
Key Concept:
Teams are harder to build than project
It is better to form a persistent team that move together from one project to the next and can take on more than one project at a time
A gelded team work together as an optimized engine and get project done
14. Mentoring, Apprenticeship, and Craftsmanship
- Craftsmanship is handed from one person to another. From elders to young and exchanged between peers.
- It a contagion, a mental virus, caught by observing others ##
Unconventional Mentoring
- Learning from a well-written manual
- Learning by observing people even when hey don’t want to or don’t care about mentoring
Evolution of a programmer
Apprentices/Interns:
- No autonomy, very closely supervised by journeymen
- Takes no tasks at all and simply provide assistance to the journeymen
- Very intense pair-programming
- Until foundational values are created. Learning and reinforcing disciplines
Journeymen:
- Trained, competent and energetic
- Are learning to work well in a team and to become team leaders (masters)
- Knowledgeable about current technology but typically lack experience with many diverse systems
- Supervised by masters or other more senior journeymen
- Work closely supervised and code is scrutinized until they gain experience and autonomy and the supervision becomes less direct and more nuanced. Eventually transitioning into peer review.
Masters:
- Programmers who have taken the lead on more than one significant software project
- Typically 10+ years of experience
- Experience with different kinds of systems, language and operating systems
- Know how to lead and coordinate multiple teams, are proficient designers and architects
- Maintain their technical role by reading, studying, practicing, doing and teaching
- The one that will be assigned technical responsibility for a project
- This description is idealized. In most companies there is no technical supervision at all
- Programmers get promotions and raises often because they are “there” and that is what you do with them
- Most of the time elders do not take the time to teach the young. That is something that must change
What is a craftsman and craftsmanship ?
Qualities:
- Skill
- Quality
- Experience
- Competence
- Works quickly
- Does not rush
- Provides reasonable estimates
- Meets commitments
- Knows when to say no
- Tries hard to say yes
- Is a professional
Mindset:
- Values
- Disciplines
- Techniques
- Attitudes
- Answers
A. Tooling
IDE
- Were you write your code
- Has features to make development easier (auto completion, .. )
- Learn to use it properly and take time to customize it for you work.
Continuous Build
- Hooks up to the source code control system
- When people check in code, it automatically build and report the status of the team
- If a build fails, it should stop the work and the team should meet to quickly resolve the issue Should not persist a day or more
- Developers run the continuous-build locally before they commit
Unit Testing Tools
- Features they should all support (and do):
- Should be quick and easy to run tests
- Should give you clear visual pass/fail indication
- Should give you a clear visual indication of progress
- Should discourage individual test cases from communicating with each other
Component Testing Tools
- For testing components at the API level
- Make sure that the behavior of a component is specified in a language that the business and QA people can understand
- Ideally QA and business can write the specifications using the tool
- Specifications are the Definition of Done Completely unambiguous. Done = All Tests Pass
Integration Testing Tools
- Component testing tools can also be used for many integration tests but are less than appropriate for tests that are driven through the UI
- End-to-End tests are usually not very many because UIs are volatile
Unified Modeling Language (UML)/ Model Driven Architecture (MDA)
- The dream of models is to allow developers to leave behind the details of textual code and author systems in a high-level language of diagrams
- The caveat is that modelling does not includes details that the developers has to handle in his code
Code for a teletype machine in the 70s:
Theses informations could easily be written into a model diagram:
- At the end of a line you need to go down to the next line (new line feed) (
\n
)- At the end of a line you need to go back to the start of the line (carriage return)
\r
- (Or simple “At the end of a line do a line return” which is common now since going to the next line and to the start of the line is shortened into the line return
\n
)This is the kind of __detail that wont be (shouldn’t) be written into a model__:
- You need to wait some delay when you do theses 2 actions or text will be written at the wrong place
- The behavior of
\n
or\r
is interpreter specific (some interpret\n\r
as two lines, some recognize\n\r
, others\r\n
)Line endings are a common issue even today and this kind of extra detail cannot be eliminated by a picture representation that diagrams are
The difference in the level of abstraction between code and diagrams is tiny at best.