More on this book
Community
Kindle Notes & Highlights
Read between
December 16, 2017 - January 4, 2018
Professionalism is a loaded term. Certainly it is a badge of honor and pride, but it is also a marker of responsibility and accountability.
The fact that the task to write perfect software is virtually impossible does not mean you aren’t responsible for the imperfection.
the first thing you must practice is apologizing.
As you mature in your profession, your error rate should rapidly decrease towards the asymptote of zero. It won’t ever get to zero, but it is your responsibility to get as close as possible to it.
It is unprofessional in the extreme to purposely send code that you know to be faulty to QA. And what code do you know to be faulty? Any code you aren’t certain about!
This philosophy is sometimes called merciless refactoring. I call it “the Boy Scout rule”: Always check in a module cleaner than when you checked it out. Always make some random act of kindness to the code whenever you see it.
Do you know what a Nassi-Shneiderman chart is? If not, why not? Do you know the difference between a Mealy and a Moore state machine? You should. Could you write a quicksort without looking it up? Do you know what the term “Transform Analysis” means? Could you perform a functional decomposition with Data Flow Diagrams? What does the term “Tramp Data” mean? Have you heard the term “Conascence”? What is a Parnas Table?
Here is a minimal list of the things that every software professional should be conversant with: • Design patterns. You ought to be able to describe all 24 patterns in the GOF book and have a working knowledge of many of the patterns in the POSA books. • Design principles. You should know the SOLID principles and have a good understanding of the component principles. • Methods. You should understand XP, Scrum, Lean, Kanban, Waterfall, Structured Analysis, and Structured Design. • Disciplines. You should practice TDD, Object-Oriented design, Structured Programming, Continuous Integration, and
...more
It is the responsibility of every software professional to understand the domain of the solutions they are programming.
It is the worst kind of unprofessional behavior to simply code from a spec without understanding why that spec makes sense to the business. Rather, you should know enough about the domain to be able to recognize and challenge specification errors.
Professionals speak truth to power. Professionals have the courage to say no to their managers.
the hard decisions are best made through the confrontation of adversarial roles.
most managers know how to do that job pretty well. Part of that job is to pursue and defend their objectives as aggressively as they can.
My experience is that the why is a lot less important than the fact.
The worst thing Paula could do in response to Mike’s manipulations is say “OK, we’ll try.” I hate to channel Yoda here, but in this instance he is correct. There is no trying.
What extra effort could Paula apply to get the demo ready in time? If there is extra effort she could apply, then she and her team must not have been applying all their effort before. They must have been holding some effort in reserve.1
The promise to try is an admission that you’ve been holding back, that you have a reservoir of extra effort that you can apply.
There are three parts to making a commitment. You say you’ll do it. You mean it. You actually do it.
What’s important about this sentence? You’re stating a fact about something YOU will do with a clear end time. You’re not talking about anyone else but yourself. You’re talking about an action that you will take. You won’t “possibly” take it, or “might get to it”; you will achieve it.
You’re taking full responsibility for something, in front of an audience of at least one person. It’s not just you standing in front of the mirror, or the computer screen. It’s you, facing another human being, and saying you’ll do it. That’s the start of commitment. Putting yourself in the situation that forces you to do something.
You can only commit to things that you have full control of.
If the end goal depends on someone else, you should commit to specific actions that bring you closer to the end goal.
If you can’t make your commitment, the most important thing is to raise a red flag as soon as possible to whoever you committed to.
Indeed, one of the complaints I often hear about pairing is that it blocks entry into the Zone. Good! The Zone is not where you want to be.
Hope is the project killer. Hope destroys schedules and ruins reputations. Hope will get you into deep trouble.
Therefore you should not agree to work overtime unless (1) you can personally afford it, (2) it is short term, two weeks or less, and (3) your boss has a fall-back plan in case the overtime effort fails.
Because of this, it is the responsibility of programmers to be available to help each other. It is a violation of professional ethics to sequester yourself in a cubicle or office and refuse the queries of others.
Therefore, since for many of us collaboration is not an instinct, we require disciplines that drive us to collaborate.
You are not allowed to write any production code until you have first written a failing unit test. You are not allowed to write more of a unit test than is sufficient to fail—and not compiling is failing. You are not allowed to write more production code that is sufficient to pass the currently failing unit test.
This is one of the most powerful benefits of TDD. When you have a suite of tests that you trust, then you lose all fear of making changes. When you see bad code, you simply clean it on the spot. The code becomes clay that you can safely sculpt into simple and pleasing structures.
Each of the unit tests you write when you follow the three laws is an example, written in code, describing how the system should be used.
The unit tests are documents. They describe the lowest-level design of the system. They are unambiguous, accurate, written in a language that the audience understands, and are so formal that they execute. They are the best kind of low-level documentation that can exist.
It is often difficult to test a function if that function calls other functions. To write that test you’ve got to figure out some way to decouple the function from all the others. In other words, the need to test first forces you to think about good design.
One way to stay ahead of the curve is to do what lawyers and doctors do: Take on some pro-bono work by contributing to an open-source project.
I learned that their vision of the features does not often survive actual contact with the computer.
In the end, the more precise you make your requirements, the less relevant they become as the system is implemented.
They know they must estimate the system and often think that this requires precision. It doesn’t.
Professional developers understand that estimates can, and should, be made based on low precision requirements, and recognize that those estimates are estimates.
Professional developers don’t flesh out a requirement until they are just about to develop it.
Often stakeholders disagree. When they do, they may find it easier to wordsmith their way around the disagreement rather than solve it. They will find some way of phrasing the requirement that they can all agree with, without actually resolving the dispute.
In this chapter we will define acceptance tests as tests written by a collaboration of the stakeholders and the programmers in order to define when a requirement is done.
Professional developers have a single definition of done: Done means done. Done means all code written, all tests pass, QA and the stakeholders have accepted. Done.
Acceptance tests should always be automated.
Following the principle of “late precision,” acceptance tests should be written as late as possible, typically a few days before the feature is implemented.
The first few acceptance tests should be ready by the first day of the iteration. More should be completed each day until the midpoint of the iteration when all of them should be ready.
Acceptance tests are written by the business for the business (even when you, the developer, end up writing them).
Acceptance tests invoke the system much farther out, at the API or sometimes even UI level.
The trick is to design the system so that you can treat the GUI as though it were an API rather than a set of buttons, sliders, grids, and menus.
There is a design principle called the Single Responsibility Principle (SRP). This principle states that you should separate those things that change for different reasons, and group together those things that change for the same reasons.
Every time someone commits a module, the CI system should kick off a build, and then run all the tests in the system.