Clean Coder — Robert Martin
The only book I’ve read that talks about how to be a professional. It’s extremely insightful, encouraging you to take responsibility, and be a better professional in this very young industry. It has great examples to help you figure out what you’re doing wrong and how to do it right.
My rating: 5/5. It was awesome.
My notes length: 12 min.
Date read: September 09, 2017. More information on Amazon.
Professionalism is all about taking responsibility. — Robert Martin
Don’t take pride or honor in something that you won’t be held accountable for.
Software is too complex to create without bugs. Unfortunately that doesn’t let you off the hook. The human body is too complex to understand in it’s entirety, but doctors still take an oath to do no harm. — Robert Martin
You will create bugs, you will make errors. Learn to apologize and be responsible for the bugs you create. Fix them and learn from them.
Increase your confidence in your code by testing it. And then test it again, and up, and down, and from side to side.
Only write code you expect to get executed, not “just-in-case” code. If you expect your code to be executed, write a test for it. Design and write code that’s easy to test.
Get 100% coverage with automated tests that you can run whenever you want wherever you want. It’s not a suggestion, it’s a requirement. It will not catch everything but less coverage can catch less errors, never more.
If you don’t get 100% coverage or when automated tests are not enough, your automated test suite must tell you, at the very least, if your system is likely to pass QA tests.
To your knowledge, QA should find nothing. Don’t rely on QA to do the testing for you. Whenever a bug passed through you, figure out why and do something to prevent it from happening again.
Never compromise the structure of your code. The structure of your code allows you to be flexible in the future. Compromising it is compromising your future.
This is completely counter to the way most people think about software. They think that making a continuous series of changes to working software is dangerous. No! What is dangerous is allowing the software to remain static. If you aren’t flexing it, then when you do need to change it, you’ll find it rigid. — Robert Martin
Always make changes to your code. Make sure that whenever you find that a change is hard to make, refine your design so that the next change will be easier.
Saying “no” and “yes”
Learn how to say “no” to your managers. Professionals are expected to say “no”, to aggressively defend your point of view just as managers defends them. Finding the best outcome usually takes negotiation between manager and engineer.
Negotiation involves clearly identifying what everyone wants, being able to do deliver in the given time, removing less wanted or less valuable features and focusing only on the most important parts, if needed.
Negotiation cares more about facts rather than whys. Why something will take more time is a lot less important than the fact that it will take more time. Too many details encourages micromanagement.
Learn how to say “no” specially when the stakes are high. A team player is not someone who says “yes” all the time, but someone who works for the best outcome, helping others as needed.
Never say that you’ll try harder. It assumes that you’re not already working the best you can. If you say you’ll try, most people will interpret it as a commitment.
Learn to recognize the different ways people asks you to try harder:
- “Can you work smarter and get creative?” “We’re all pretty creative, we’re not holding back.”
- “Can you work overtime?” “That will just make us go slower with overly tired engineers.”
- “I know you’ll figure something out.” “No, we won’t, we have to scope down the project.”
If you are not holding back some energy in reserve, if you don’t have a new plan, if you aren’t going to change your behavior, and if you are reasonably confident in your original estimate, then promising to try is fundamentally dishonest. You are lying. — Robert Martin
Know how much overtime you can effectively apply, where the limit is, and what it will cost. This is a negotiation tool that you can apply if the situation requires it.
The only way to truly say “yes” is if you’re unafraid to say “no”.
Never leave your professionalism aside to solve a problem quickly. Not being professional is the way you create problems.
Learn to identify non-commitments. A non-commitment usually use ambiguous words such as: need/should, hope/wish, let’s.
Learn to identify a commitment. It’s composed of three parts: saying you’ll do it, meaning it, and then actually doing it. They state a fact or action about what you—not anyone else or something else—will do in the future.
Only commit to things you have full control. If it can’t be done, commit to the actions you will do to get you closer.
Raise a flag as soon as you find out you won’t be able to make a commitment. If you don’t let anyone know, you’re not giving anyone a chance to help you follow through your commitment.
Professionals spend time caring for their profession. — Robert Martin
Be responsible for your career by staying up to date and improving your skills. It’s not your employer’s responsibility, it’s yours.
Study and understand the domain of the solutions you’re solving. You should be able to recognize and challenge specification errors.
Plan on working 60 hours a week: 40 hours for your employer and 20 hours for you.
The minimum things you must know are:
- Design patterns: GOF and POSA books.
- Design principles: SOLID and component principles.
- Methods: XP, Scrum, Lean, Kanban, Waterfall, Structured Analysis, and Structured Design.
- Disciplines: TDD, OOD, Structured Programming, CI/CD, and Pair Programming
- Artifacts: UML, DFDs, Structure Charts, Petri Nets, State Transition Diagrams and Tables, Flow Charts, and Decision Tables.
Learn things outside of your comfort zone. Learn Prolog and Forth.
Do a simple 10-minute programming exercise in the morning, to warm up, and in the afternoon, to cool down.
Mentor junior engineers. Don’t let them flail about unsupervised.
Be humble. Fight off the act of supreme arrogance that comes with programming—creating something out of nothing, building solutions to problems, bringing order into chaos.
Never ridicule others, but accept ridicule when it’s deserved and laugh it off when it’s not. Never demean others for making a mistake, you can be the next.
Take care of your sleep, health, life, and lifestyle. Professionalism is more about consistency and good 8 hours of work rather than simply working more time.
Programming and Practicing
Coding is an intellectually challenging and exhausting activity. — Robert Martin
Don’t code if you’re tired or distracted. Rest or eliminate the distractions.
If you’re worried or anxious about something, time-block it. Dedicate maybe one hour to solve the issue. Even if it’s not solved, you’ll probably have reduced how much it distracts you.
Be careful about programming while in the Zone. Even though working in the Zone makes you feel you’re going fast, you’ll probably lose the big picture and will end up rewriting things.
Conserve your energy and creativity. When you’re tired, rest for a while. If you’re blocked and the solution doesn’t come to you, find a pair partner.
Software development is a marathon, not a sprint. — Robert Martin
TDD works. Get over it.
- Write a test before any line of production code.
- Write one and only one failing test, not compiling counts as failing.
- Write the minimum production code that passes the test.
Your tests are documentation. It’s the lowest-level design of the system.
Don’t fear cleaning up. Professionalism leads to steadily improving codebases instead of letting them rot.
TDD is the professional option. It is a discipline that enhances certainty, courage, defect reduction, documentation, and design. — Robert Martin
Don’t follow a guideline if the guideline does more harm than good.
When performance matters, professionals practice. — Robert Martin
Do programming katas. They are choreographed keystrokes and mouse movements that simulates solving a problem. You should already know the answer.
Practice programming katas to train your brain and fingers how to move and react. Practice until you know several different katas.
Solve a programming kata with a partner. One programmer writes a unit test, and then the other must make is pass. Then reverse the roles.
Practicing is what you do when you aren’t getting paid. You do it so that you will be paid, and paid well. — Robert Martin
Acceptance and Testing
Always make sure your communication with other members of the team, and the business, are accurate and healthy.
Consider that customers are not completely sure of what they’re asking. As soon as they see something working, they get a better idea of what they want and they will change the requirements. This is not only common but expected.
Clear requirements doesn’t necessarily mean precise. The same is true about estimations. There are intrinsic uncertainties.
Work on making the requirements precise only when you’re about to start developing it.
Shipping without tests to ship on time, to save face, is irresponsible. It’s not thinking on your customer or employer who expects a professional.
There is only one definition of “done”: all code is written, all tests pass, and QA and the stakeholders have accepted it.
Acceptance tests are tests written by a collaboration of the stakeholders and the programmers in order to define when a requirement is done. — Robert Martin
It’s your responsibility to drive the requirements all the way to automated acceptance tests. This is work, but it’s not more work than defining a manual test plan and definitely less work than repeatedly executing it.
Automated acceptance tests will prevent you from implementing the wrong system and will allow you to know when you’re done.
Just as with requirements, write the acceptance tests only when you’re about to start developing the requirement.
The role of QA is to work with the business to define the expected behavior of corner and error cases and to do exploratory testing to characterize the true behavior of a system.
Test automation pyramid:
- Unit tests: By programmers for programmers. Should cover ~100% of the code.
- Component tests: By QA and business with assistance from development. Because components encapsulate business rules, these includes acceptance tests. Should cover ~50% of the code.
- Integration tests: By systems architects, or lead designers, of the system. Only useful for large systems with many components. Tests how the assembly of components works together, not the business rules. Can be skipped from CI because they usually take more time to run, but they have to be executed periodically. Should cover ~20% of the code.
- System tests: Tests against the entire system to make sure everything is wired correctly. Usually written at the UI level. Performance tests are usually in this category. Should cover ~10% of the code.
- Manual exploratory tests: Not automated nor scripted tests. These tests explores the system for unexpected, or inconsistent, behavior while confirming expected behaviors. Not focused on coverage but on how the system behaves with a human.
Professionals evaluate the priority of each task, disregarding their personal fears and desires, and execute those tasks in priority order. — Robert Martin
You are responsible of knowing what to do and how to make effective use of the eight hours you work per day.
Meetings are both necessary and time wasters. The person inviting you to a meeting isn’t responsible of managing your time.
Don’t attend to meetings without an immediate and significant benefit to the job you’re doing right now.
When invited to contribute to a meeting, decide if the loss to your project is worth the benefit to theirs.
If you lose interest in a meeting, leave. Ask, at the opportune moment, if your presence is still necessary.
For every meeting ask about the discussions that will take place, the agenda, the time allotted, and the goal to be achieved.
If an argument isn’t solved in five minutes, make a note to follow up on it once the appropriate data is in place and follow up. Willpower doesn’t win arguments, data does.
Avoid getting vested in an idea to the point that you can’t abandon it.
Don’t suggest or agree on working on two projects at the same time. There’s no such thing as “half a person”.
Realize that the business views estimates as commitments while developers view estimates as guesses.
Don’t make commitments unless you know you can achieve it. Don’t even imply you’re committing to something you don’t know if you can do.
Make estimates. If needed, communicate the probability distribution of the estimate.
If you are going to commit, provide hard numbers. If not, provide probabilistic estimates.
- \(O\): Wildly optimistic estimate. Less than 1% of occurrence.
- \(N\): Nominal estimate. Greatest chance of success.
- \(P\): Wildly pessimistic estimate. Less than 1% of occurrence.
With these three values, the expected duration of the task is:
The standard deviation of the probability distribution is:
The estimated duration of a sequence of tasks is:
And the standard deviation of the probability distribution of a sequence of tasks is:
Always stay calm under pressure.
Avoid scenarios that cause pressure. Avoid committing to deadlines that you’re not sure you can meet. It’s fine to try to help the business when commitments are imposed, but you don’t have to accept them.
Resist the temptation to create a mess only to try to go quickly. That never works in the long run.
Choose behaviors that you would follow during a crisis. Realize that your behavior during a crisis is what you truly believe on. Follow your decisions all the time.
Working more hours is not sustainable. Slow down, think the problem through, plot a course of action, and follow it at a reasonable and steady pace.
When the pressure is on, find someone who’s willing to pair program with you. If you see someone under pressure, offer to pair program with them.
Your first responsibility is to your employer. Understand why you’re writing the code you’re writing and how your employer will benefit from it.
Share what you learn. Document what you do.
You may work better alone, but the team doesn’t benefit from you working alone. Face each other, hear their frustrations, smell their fear, and offer help. Work as a unit.
Teams are harder to build than projects. Suggest to keep sub-teams working together from project to project.
Be a craftsman:
- Work quickly but without rushing.
- Provide reasonable estimates and meet your commitments.
- Know when to say “no” and when to say “yes”.
- Be a professional.
It’s your responsibility to teach and mentor young engineers. Nobody out of college is prepared enough for the industry. Teach consistency, practice, and the skills of being a craftsman.