Skip to content

Lessons from The Mythical Man-Month

Published:

There are some important books that every developer should read, such as The Mythical Man-Month, Pragmatic Programmer, Clean Code, etc. However, developers may sometimes feel lazy when it comes to reading. To help with that, I have prepared key takeaways for some chapters in The Mythical Man-Month. Not all chapters will have key takeaways, as the book is relatively old and some topics may be outdated. Nonetheless, I have done my best to summarize the relevant information.

Chapter 1. Tar Pit

Chapter 2. The Mythical Man-Month:

Chapter 3. Surgical Team

Chapter 4. Aristocracy, Democracy, and System Design

Chapter 5. Second-System Effect

Interactive Discipline for the Architect

For this key takeaway we need a little bit of context, so here is direct quotation from the book:

For builder to be successful, the architect must:

- Remember that the builder has the inventive and creative responsibility for the implementation; so the architect suggests not dictates

- Always be prepared to suggest a way of implementing any thing he specifies, and be prepared to accept any other way that meets the objectives as well;

- Deal quietly and privately in such suggestions;

- Be ready to forego credit for suggested improvement

Take away of Interactive Discipline for the Architect

A common scenario is when a senior or lead developer writes specifications for a solution or implementation. However, since they may not be as involved or have a full comprehension of that part of the system, the specifications may not reflect the real requirements. In such cases, the implementer or builder steps in to make additional implementations or even rewrites some of them to make everything easier and more understandable. If the changes are really impactful and useful for the project, the senior or lead developer should allow the implementer or builder to keep them.

Take away of Second-System Effect

When working on a new project or in an unfamiliar domain, it’s natural to be cautious and take measures to avoid issues. However, as we gain more knowledge and confidence, we tend to overcomplicate things by adding unnecessary complexity. This results in code that is difficult to maintain and hinders productivity. It’s important to keep projects as simple as possible, as simplicity is the ultimate form of sophistication.

Chapter 6. Passing the Word

Chapter 7. Why Did the Tower of Babel Fail?

Chapter 8. Calling The Shot

Chapter 10. The Documentary Hypothesis

Chapter 11. Plan to Throw One Away

However, we should not simply discard the first prototype, or pilot; instead, we should learn from it and redesign the new system with improved ideas. Like any other system, software changes over time, as our end users’ perceptions and needs evolve with the program’s development, testing, and use.

Each feature introduced into the program to keep up with these changes should be carefully tested.

Chapter 12. Sharp Tools

The manager should allocate resources to develop commonly used packages. This includes developing shared libraries, UI components, code snippets, and other useful tools. Additionally, it’s important to recognize that some developers may have their own preferred methods of working. Therefore, their input should be considered and not disregarded.

Chapter 13. The Whole and the Parts

This chapter explores ways to design software without bugs. One effective method for preventing bugs is to maintain conceptual integrity, as previously discussed. This is because bugs often arise from mismatched assumptions among team members regarding the product.

To prevent bugs, specifications should be crystal clear. Otherwise, developers may invent their own solutions to problems. As Vyssotsky once said, “They won’t tell you they don’t understand; they will happily invent their way through the gaps and obscurities.”

The top-down approach (also known as stepwise design and refinement, and sometimes used synonymously with decomposition) is vital for designing bug-free software. It involves breaking down a problem into smaller tasks, applying a solution to each task, evaluating the results, and determining how far they deviate from the desired outcome. From there, we can break down these results into even smaller steps and develop the rest of the features and programs as modular components. With modular design, we can test individual steps easily, as they are clearly separated and partitioned. Each module contains its own logic, making it easy to avoid system-wide bugs. This does not mean that we will never have to start from scratch if requirements change, but with this approach, we can do so more easily because the system is modularized.

It is highly beneficial to test each part separately with unit tests and appropriate fixtures. In the book, this is referred to as a “dummy component.”

When introducing new features, it is best to add programs and functions one at a time rather than batching all changes into a single step. By updating the system with each new feature as it is completed, you can reduce regression. If something goes wrong in the update process, it will be easier to detect.

Chapter 14. Hatching a Catastrophe

Chapter 15. The Other Face

The program should be “self-documenting”; there shouldn’t be separate documentation for the code and the users. The code should be easily understandable at first glance and easy to reason about. To achieve this, we must use mnemonic names, avoid branching as much as possible, and occasionally comment if the code is abstract or involves complex regex queries.

Chapter 15. No Silver Bullet

Software is inherently complex, and it’s something we must accept. As the quote goes, “The complexity of software is an essential property, not an accidental one.” Therefore, our goal should be to abstract that complexity for the future, for our team members, and for the sake of maintainability of the product.

Conformity is another crucial aspect of software development. Since software has to follow specifications, guidelines, and user needs, it can be challenging to ensure that it adheres to all these rules.

Changeability is yet another aspect of software complexity. Software is constantly evolving to meet the changing needs of its users, and we must be prepared to adapt accordingly.

One of the gifts and curses of software is its invisibility. While it can be difficult to grasp and communicate, we can also easily abstract concepts.

While there have been numerous breakthroughs in the programming world, such as high-level languages, object-oriented programming, and artificial intelligence, there is no silver bullet in the world of computers. As the quote goes, “The hard thing about building software is deciding what to say, not saying it.” This means that determining the software’s intended functionality and behavior is often more challenging than actually writing the code.

The concept of “Buy versus Build” is a significant breakthrough in software development. To deliver quickly and with minimal hassle, it’s often better to buy Software as a Service (SaaS) and Data as a Service (DaaS). This approach allows the provider to maintain the software, reducing the burden on the development team.

Incremental development is also crucial, as perfection cannot be achieved on the first try. By taking an incremental approach to development, we can build a system and add new features gradually, based on the needs and behaviors of the customers and users.

Lastly, having a great designer or architect is a crucial step in preventing issues before they arise.

Overall, software development is complex, but by abstracting complexity, adhering to guidelines and specifications, adapting to change, buying versus building, incremental development, and having a great designer or architect, we can build successful software products.