This post is part of a series of posts with my personal notes about the chapters in the book “The mythical man-month” by Frederick P. Brooks. I write these posts as I read through the book, and take notes on the concepts I find more relevant. I do, however, advise reading the book to get the full benefit out of it.
Curiously enough, Brooks starts this chapter by mentioning something I say every once in a while:
The challenge is not simply to build something that “works”. It is to build something that really works in the way the end user needs it to work, with conceptual consistency, minimal technical bugs, and that can be maintained and extended throughout a long life.
Bulletproofing the definition
The product concept must make sense as a whole, not just in each component.
Having conceptual integrity throughout the application will make it easier to understand and use by the end users, but it will also make it easier to build and less subject to bugs.
Brooks quotes V. A. Vyssotsky:
The crucial task is to get the product defined. Many, many failures concern exactly those aspects that were never quite specified.
Defining what a feature does, how it fits in the global product vision, having cleat specifications, having a process to clear up any ambiguity… these are all crucial elements in defining what we need to build, and they can save us, and the end users, a lot of headaches.
All this makes me think of all those practices that came to be, almost 20 years later, through the adoption of Agile and Domain Driven Design principles and methodologies, which focus exactly on having a clear idea of the Domain and what needs to be built.
To describe the ideal design process, Brooks refers to Niklaus Wirth, who formalized a work division in three stages:
- Realisation (testing).
Each of these stages could be done in a top-down approach, starting a highly abstract definition and iteratively refine and split work into smaller, more manageable, units of work, as needed.
As I read this, I can’t avoid relating this to the way I am used to preparing work nowadays:
High level, medium and/or long term goals;
Functionality needed to achieve the goals specified in the initiatives;
Independent features needed to achieve each epic;
Technical tasks needed to achieve each story, which should be independently developed and/or independently deployed.
All of these should be planned in iterative, successive refinements as needed, throughout a quarter, semester, or whatever unit of time the initiatives were designed to be achieved.
Brooks proceeds to talk about the impact of structured programming and all the debugging styles.
All of that is outdated, of course, but I think the principles still remain and I would rewrite them in today’s context as:
- Choose the right programming language for the job at hand;
- Use a debugger that is interactive and allows us to debug both logic and memory state.
Brooks defended that there should be only one person in charge of authorizing changes, replacing versions and maintaining the several versions of the system.
I see this as the pre-historic version of a Version Control System, as it could be implemented in the 1970s. Nowadays, of course, we use tools designed for that purpose alone, like git or subversion.
Add one component at a time
This is also something that, as for my experience, we try to adopt as a best practice nowadays:
- Develop features with small incremental merges to master;
- Focus our tests on testing module behaviours and stubbing, or even mocking, other modules.