In 1975, Frederick P. Brooks, Jr., a professor and Chairman of the Computer Science Department at the University of North Carolina at Chapel Hill, reflected on his experiences as a software engineer for IBM. Known as the “Father of the IBM System/360,” he played a major role in the triumphs--and setbacks--of 360 as a project manager for IBM. After he analyzed his experiences, he wrote a collection of essays about what he learned and what he suggests for future programmers called The Mythical Man-Month. The key takeaways from his experience led him to address the issues of division of labor, planning, design integrity, documentation, and communication.
Brooks begins by comparing large-system programming at the time to a tar pit. The two situations are similar because when programmers found themselves in sticky situations, the tendency was to add more people to the job. But then those people also found themselves bogged down, just like animals in tar pits. Back in the Ice Age, a mammoth might have wandered into a tar pit and consequently found itself stuck. Other mammoths might have attempted to wade in to help. But they also became stuck. Their efforts were futile, and centuries later they would be mere fossils. Perhaps programming doesn’t present such a dire situation, but Brooks recognized that along with the joys of programming there were also woes and serious pitfalls.
Brooks highlights the perks of programming:
- You get to experience the joy of making something
- You can make something that is useful to others
- Programming is like solving a fascinating, complex puzzle
- You are always learning
- You get to work in a tractable medium
But he also highlights the drawbacks:
- Programmers have to aim to be perfect
- Other people can set your objectives
- You might have to rely on others for resources and information
- If you’re part of a team, you have to depend on others
- While designing is fun, finding bugs is tedious
- Debugging your program can drag on longer than expected
It is dealing with these drawbacks that leads to the crux of Brooks’ writing: misuse of time, people, and resources. “More software projects have gone awry for lack of calendar time than for all other causes combined,” according to Brooks. Why? At the time, techniques for estimating weren’t well developed, and there was an assumption that everything would go as planned. Programmers were optimistic. It was also difficult to monitor progress. Developers were using the “man-month” as a unit to measure how long a project would take, but it just wasn’t accurate. Consequently, when problems arose, there was an instinct to add more people to the project, or add more man-months. These attempted solutions didn’t have the desired effect for a handful of reasons. First, dividing a task to get more people working didn’t speed it up. Second, new programmers had to be trained in the technology and educated on the objectives and plan. Third, intercommunication required more time and effort. It was easier to communicate between two people instead of three.
Brooks suggested that a project schedule allows for more time to plan and leaves half the time for debugging, since that will always take longer than expected. He also recommended utilizing a small team of top programmers, akin to a “surgical” approach. Brooks used this analogy to highlight how a good programming team could operate. Behind every surgeon, there is a team of people with specific jobs and they are all working toward a common goal. A programming team should be the same way. The programmer is the chief surgeon, and when everyone else has a clearly defined role and understands the objective, when everyone can communicate clearly and be on the same page, then chances for launching a successful software--like completing a successful surgery--are increased.
In many ways, Brooks’ suggested methods are even easier to attain today. Advances in technology have, of course, eliminated some of the problem areas he highlighted. Today, email makes it easy to efficiently communicate with a large number of people. Software programs can help track workflow and improve time management. And modern testing services can help you find and fix bugs faster than ever by integrating with your workflow. Testing can be performed through each design phase, and whereas traditional testing might have proved a lengthy process, tests today can yield results in less than 24 hours, especially with the force multiplier of crowdtesters. These advancements also help bring the programmer’s idea to fruition and ensure the integrity of the design plan, which Brooks considered to be paramount.
“I will contend that conceptual integrity is the most important consideration in system design,” Brooks said. He wanted design teams to consider Reims Cathedral. Reims is an architectural anomaly because generation after generation stuck with the original design plan. Too often, in architecture and software design, later generations come along and try to add onto or modify the original design plan, but too many different and uncoordinated ideas will not necessarily improve the product.
Brooks also spoke to “the second-system effect.” Continuing with the architectural/builder relationship, he said that an architect’s first build tends to be simple, but as they are designing, they hatch and store ideas and embellishments for future designs. When the time comes to create the second design, there is then a tendency toward overdesigning. The same can be said of software designers. Sometimes more isn’t more. To avoid overdesigning, as per the second-system effect, Brooks suggested you be aware “of the peculiar hazards of that system, and exert extra self-discipline to avoid functional ornamentation.” Along the same vein, he also cautioned against trying to stuff ten pounds of goods in a five-pound sack. What does he mean? Quite simply, a programmer has to study users and their applications and then budget all the aspects of the size of the software. These principles hold true even today. No user wants a program or application that tries to do so much that they are overwhelmed. Nor do they want software that uses up too much storage, battery life, or memory.
Speaking of builds, let’s go back to that first build for a moment. Brooks focused one chapter on that first build. He called that chapter “Plan to Throw One Away.” Now it’s hard to imagine spending a lot of time and resources on designing software or an application that you will discard. But Brooks felt you should do just that because the first build would hardly be usable. He suggested it would be too slow or too big or too awkward to use--or all of those. Planning to throw one away prevents programmers from becoming too attached to design features when users’ needs might call for change. The idea of throwing one away seems a bit drastic in modern times. But the core principle--the willingness to make changes to meet ever-changing user needs and demands--is certainly still relevant. Software designers today are able to take much more agile approaches to design and can perform continuous testing to improve on their original. Decades ago, designers and programmers had little-to-no interaction with their users. Today, users provide all sorts of feedback. So while you don’t need to necessarily throw one away, you do need to be willing to take criticism and make changes quickly. Many companies are fostering a DevOps culture, where they can be agile and customer-centric enough to continuously deliver new product iterations and features.
A significant component of creating this type of culture is communication. Earlier, we looked at how Brooks felt a smaller team was more beneficial than a larger team because there would be fewer people to have to communicate with. That’s not really a concern today with easy communication enabled by email, video conference calls, and more. But regardless of your team size, the idea that everyone is speaking the same “language,” that everyone is following the same plan, and that everyone has access to project documents was a guiding principle for Brooks and should be a guiding principle for modern designers. A project manager is wise to have thorough documentation for the build.
Brooks said these documents contain the essentials:
- What: Project objectives, goals, constraints, and priorities
- What: Product specifications
- When: Project schedule
- How much: Project budget
- Where: Space allocations
- Who: Organization chart and divisions of labor
Thorough documentation gives a project manager the opportunity to see where there are holes and inconsistencies, while also providing a database and checklist.
If modern software designers and programmers can maintain open lines of communication, set clear objectives and stick to them, prepare to make changes, then there is just one more thing to consider according to Brooks: your design tools. By using “sharp tools,” you can get the job done effectively. Little slippages can become very problematic, but remember, the solution isn’t always to throw more people on the project. You don’t need more man-months. You just need the right people using the right tools. It’s practically impossible to design a bug-free software, no matter how hard you try. Software testing is a modern solution that can be performed throughout the software development life cycle. By detecting bugs early on, you will avoid setbacks and improve your odds of delivering a quality product.
Brooks concluded The Mythical Man-Month by saying: “The tar pit of software engineering will continue to be sticky for a long time to come.” Here we are over 40 years later. It’s not quite so sticky a tar pit with the advances we’ve experienced in technology, but there are certainly many kernels of wisdom modern programmers and software designers can take from Brooks’ experiences to build solid software time and again.