Saturday, September 16, 2017

Notes about the Clean Coder Book

This book's main theme is software developer's professionalism. I like this book much less than Uncle Bob's Clean Code book (the first of the series). That said, it is still a worthy read. Robert C. Martin introduces his book as a catalog of his own errors. He says we are in dire need for professionalism in our software developer profession.

Chapter 1 - Professionalism

Professionalism is all about taking responsibility. The first rule is to do no harm. As it is virtually impossible to create a bug-free code, the first thing to learn is apologizing. The code has to be tested. Then tested again. The tests must be automated. Basically the QA should find nothing. Uncle Bob demands 100% code coverage by tests. At the very least, your automated tests should assure you that the code will most likely pass the QA.

If you find a code which is hard to work with, do the refactoring to make the change easier next time. This is the Boy Scout rule: "Always check in a module cleaner than you checked it out."

You should plan to work 60 hours weekly. 40 hours are for your employer and 20 hours are for you. You should be reading, practicing, learning and otherwise developing your career. You should be conversant with:
  • Design patterns - all 24 of GOF patterns and a working knowledge of many of the POSA books.
  • Design principles - SOLID and component principles.
  • Methods - XP, Scrum, Lean, Kanban, Waterfall, Structured Analysis and Structured Design.
  • Disciplines - TDD, OOD, Structured Programming, Continuous Integration and Pair Programming.
  • Artifacts - UML, DFDs, Structure Charts, Petri Nets, Transition Diagrams and Tables, flow charts and decision tables.
Uncle Bob also introduces "katas" here. Kata is a 10 minutes warm-up exercise in the morning and 10 minutes cool-down in the evening. You program a simple problem, which you already know the solution to, just to train your fingers.

The second best way to learn is to collaborate with other peers, e.g. during pair programming. The best way to learn is to teach.

Professionals know their domain. They identify themselves with their employers. Their employers problems are their problems.

Professionals are also humble. They will not make fun of others for their mistakes, because they know they could be the next to make one.

Chapter 2 - Saying No

To reach the best possible outcome of an argument (e.g. about project deadline), you have to say no sometimes and then work out a solution that is agreeable by both parties. WHY part is just a detail, but the fact that e.g. the deadline is unfeasible is important. The most important time to say no is when stakes are highest.

There is no trying. Promising to "try" is admission that you have been holding back, that you have reservoir of extra effort that you can apply.

Uncle Bob suggests against passive aggressive behavior, when you, knowing that a disaster is coming, protect your back by keeping all the important memos, which clearly show what you told your manager and when. Uncle Bob advises to try to talk to the supervisor manager instead, even if it is jumping above heads.

Chapter 3 - Saying Yes

There are 3 parts of a commitment:
  1. You say you'll do it.
  2. You mean it.
  3. You actually do it.
You can recognize lack of commitment by detecting these keywords:
  • Need / should
  • Hope / wish
  • Let's
The commitment looks like this - you are taking full responsibility for something in front of audience of at least one person. If you depend on anyone else, you have to phrase the commitment in more specific actions that can bring you closer to the end goal. If you find any obstacles, you should inform somebody ASAP to give them a chance to help you to fulfill your commitment.

When you are out of time, it is wrong to break the discipline. You won't get done faster if you don't write tests. You won't get done faster if you don't refactor. You won't get done faster if you omit full regression suite. Breaking disciplines only slows us down.

Professionals are not required to say yes to everything. However, they should be creative to find ways to make "yes" possible. When they say yes, they use language of the commitment so that there is no doubt what they've promised.

Chapter 4 - Coding

This chapter is series of random advice about coding. The key to coding mastery is confidence and error-sense. If you are tired or distracted, do not code. Avoid the zone, or you might loose the big picture. Many people don't code well while listening to music. If you have a writer's block, find a pair partner. TDD might reduce debugging time 10 times. The trick to managing lateness is early detection and transparency. Do not be tempted to rush. 

You should not work overtime unless:
  • You can personally afford it.
  • It will not take more than 2 weeks.
  • Your boss has a fallback plan if overtime doesn't work.
To avoid false delivery, we should have and independent definition of done. The best way to achieve this is by having business analysts and testers create automated acceptance tests.

You should help others. You will likely learn more than you gave. On the other hand, it is unprofessional to get stuck when help is easily accessible. Since for many of us, collaboration is not an instinct, we require disciplines that drive us to collaboration.

Chapter 5 - Test Driven Development

TDD works and everybody needs to get over it. The 3 laws of TDD:
  1. You are not allowed to write any production code until you have first written a failing unit test.
  2. You are not allowed to write more of a unit test than is sufficient to fail - and not compiling is failing.
  3. You are not allowed to write more production code that is sufficient to pass the currently failing unit test.
Benefits: Certainity, Defect reduction, Courage, Documentation (where is the first place you go for documentation? if you are a programmer, you look for examples), Design (the tests you write after the fact are defense, the tests you write before are offense).

Chapter 6 - Practicing

Even in the '90s, long build times were the norm. Nowadays, programmers don't wait for compiles. 

A Coding Dojo is exercise when the leader types the simple program and other programmers follow him keystroke by keystroke. Programming Kata is a precise set of choreographed keystrokes that simulates the solving of some programming problem. You are practicing the movements and decisions involved in the solving of the problem. Wasa is 2-man Kata. Two partners choose a kata, one writes a test, the other one makes it pass. Then they reverse the roles.

In one way or another, professionals practice. The do this because they care about doing the best job then possibly can. Practicing is what you do when you aren't getting paid.

Chapter 7 - Acceptance Testing

The more precise you make the requirements, the less relevant they become as the system is implemented. Done means all code is written, all tests pass, QA and stakeholders have accepted. Done.

Implementation work on a feature begins then the acceptance tests for the feature are ready. It is the developer's job to connect the acceptance tests to the system, and then to make them pass. As a professional developer, it is your job to negotiate with the test author for a better test.

Unit tests and acceptance tests are documentation first and tests second.

It is hard to specify GUI upfront. People want to fiddle with the GUI. The trick is to design the system so that you can treat the GUI as thought it were an API rather than a set of buttons, sliders, grids and menus. Therefore when writing acceptance tests for GUI you take advantage of the underlying abstractions that don't change very frequently. Better still is to write tests than invoke the features of the underlying system through a real API rather than through the GUI. The reason is that the GUI is likely to change, making the GUI-specific tests very fragile. So keep the GUI tests to minimum. The more GUI tests you have the less likely you are to keep them.

Make sure all your unit and acceptance tests are run several times per day using your continuous integration system. If the fail, then the whole team should stop whatever they are doing and focus of getting the broken tests to pass again.

The only way to effectively eliminate communication errors between programmers and stakeholders is to write automated acceptance tests. They are the perfect requirements document.

Chapter 8 - Testing Strategies

The goal of the development group should be that the QA group should find nothing. Every time QA finds something, the development team should react in horror. They should ask themselves how it happened and take steps to prevent it in the future.

In general, business people tend to write happy path scenarios and QA writes the corner, boundary and unhappy path scenarios. The other role of QA is exploratory tests.

A professional team needs a suite of automated tests which are depicted as a test automation pyramid. 
Unit tests provide as close to 100% coverage as reasonable. Generally this number should be somewhere near 90%. It should be true coverage, not some fake tests just to cover some lines. 
Component tests cover roughly 50% of the system. They are written by the QA and business group with assistance from the development. They are usually written using e.g. Cucumber. They are directed more towards happy-path scenarios and very obvious corner cases. The vast majority of unhappy-path scenarios should be covered by unit tests and is meaningless at this level.
Integration tests are written by the architects or lead designers of the system. There could be performance or throughput tests at this level. They are typically not executed as part of CI after every commit, because they take long times. Their role is to verify the architecture of the system is sound.
System tests are ultimate integration tests against the fully integrated system. Their intent is to ensure the whole system is constructed correctly. We might see performance and throughput tests at this level.
Exploratory tests are the only manual tests from the pyramid. They are also not scripted. Their intent is the last verification of the system behavior while exploring for unexpected behavior.

Chapter 9 - Time Management

There are 2 truths about meetings:
  • Meetings are necessary.
  • They are huge time wasters.
One of the most important duties of your manager is to keep you out of meetings. Your responsibility is to your project first, so it might be wise to decline a meeting if it is not worth to sacrifice your project to theirs.

When the meeting is boring, leave. Simply ask, at the opportune moment, if your presence is still necessary.

Always have and agenda and a goal. 
Stand-up meetings should take 1 minute per person, 20s per each of the questions.
Iteration planning meetings should take no more than 5% of the iteration.
Allocate no more than 20 minutes for retrospective and 25 minutes for the demo.

Kent Beck: "Any argument that can't be settled in five minutes can't be settled by arguing." The only thing to do is to get some data.

Switching between physical and mental activities can improve your performance at both.

Pomodoro technique is recommended. You won't allow anything to disturb you for 25 minutes. You defer all the interruptions after the tomato time. Then you will deal with them and have a 5 minutes pause. Than you continue with longer pause after 4 or so tomatoes.

Professionals avoid getting too vested in an idea so they can easily leave it. They do this to avoid spending too much time in blind alleys.

Professionals are always on the lookout for the growing messes, and they clean them as soon as they are recognized.

Chapter 10 - Estimation

Business likes to view estimates as commitments. Developers like to view estimates as guesses.

Professionals communicate the probability distribution of an estimate to the management clearly, to enable them to make correct decisions. A good rule of thumb for estimation is (O +4N + P) / 6, where O is optimistic estimate, P is pessimistic one and N is realistic one.

There are many "games" for group estimations. Flying finger is about estimating with fingers under the table. The scale of the fingers is defined at the beginning of the meeting. Planning poker is similar, but with cards with values e.g. 0, 1, 3, 5, 10. In the end the stories can be assigned to buckets of size with Fibonacci numbers, e.g. 1, 2, 3, 5, 8.

What to do with too large numbers? Split the task into smaller ones. The sum of their estimates will be more precise than the large task estimate.

Chapter 11 - Pressure

As discussed previously we shouldn't commit to deadlines we are unsure we can meet. Quick and dirty is an oxymoron. Dirty always means slow. Don't skip your disciplines in a crunch. If they are the best way to work, they should be followed even in a crisis.

The trick to handling pressure is to avoid it when you can and weather it when you cannot. You avoid it by managing your commitments, following your disciplines and staying clean. You weather it by staying calm, communicating, following your disciplines and getting help.

Chapter 12 - Collaboration

We are happiest when alone focusing deeply on some interesting problem. One of the worst symptoms of dysfunctional team is when each programmer builds a wall around his code and refuses to let other programmers touch it. Professionals pair. 

Chapter 13 - Teams and Projects

We have an issue if projects are so small, that every programmer works on the project for 50% or even 25% of his time. There is no such thing as half person. The problem is worse if the rest of the people in the projects are different.

Nicely gelled team of 12 might have 7 programmers, 2 testers, 2 analysts and a project manager. Professional development organizations don't form teams around projects. They allocate projects to existing gelled teams. This is because teams are harder to form than projects. A gelled team can take more projects than one at a time.

Chapter 14 - Mentoring, Apprenticeship and Craftsmanship

What you learn at school and what you find in a job are often a very different things. The problem of most companies teaching is that the supervision is not technical. The responsibility of teaching the next generation of programmers falls on us, not universities.