Fred Brooks
Adding manpower to a late software project makes it later.
Nine women can’t make a baby in one month.
When a task cannot be partitioned because of sequential constraints, the application of more effort has no effect on the schedule. The bearing of a child takes nine months, no matter how many women are assigned.
If each part of the task must be separately coordinated with each other part, the effort increases as n(n-1)/2. Three workers require three times as much pairwise intercommunication as two; four require six times as much as two.
Having a system architect is the most important single step toward conceptual integrity. After teaching a software engineering laboratory more than 20 times, I came to insist that student teams as small as four people choose a manager and a separate architect.
The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air, from air, creating by exertion of the imagination. Few media of creation are so flexible, so easy to polish and rework, so readily capable of realizing grand conceptual structures.
The first false assumption that underlies the scheduling of systems programming is that all will go well, i.e., that each task will hike only as long as it “ought” to take. A large programming effort, however, consists of many tasks, some chained end-to-end. The probability that each will go well becomes vanishingly small.
What one programmer can do in one month, two programmers can do in two months.
Much of the essence of building a program is in fact the debugging of the specification.
Human beings are not accustomed to being perfect, and few areas of human activity demand it. Adjusting to the requirement for perfection is, I think, the most difficult part of learning to program.
Because of optimism, we usually expect the number of bugs to be smaller than it turns out to be. Therefore testing is usually the most mis-scheduled part of programming.
False scheduling to match the patron’s desired date is much more common in our discipline than elsewhere in engineering.
Sackman, Erickson, and Grant were measuring performance of a group of experienced programmers. Within just this group the ratios between the best and worst performances averaged about 10:1 on productivity measurements and an amazing 5:1 on program speed and space measurements!
Conceptual integrity is the most important consideration in system design. It is better to have a system omit certain anomalous features and improvements, but to reflect one set of design ideas, than to have one that contains many good but independent and uncoordinated ideas.
The separation of architectural effort from implementation is a very powerful way of getting conceptual integrity on very large projects.
The general tendency is to over-design the second system, using all the ideas and frills that were cautiously sidetracked on the first one.
The management question, therefore, is not whether to build a pilot system and throw it away. You will do that. The only question is whether to plan in advance to build a throwaway, or to promise to deliver the throwaway to customers.
Program building is an entropy-decreasing process, hence inherently metastable. Program maintenance is an entropy-increasing process, and even its most skillful execution only delays the subsidence of the system into unfixable obsolescence.
Chemical engineers learned long ago that a process that works in the laboratory cannot be implemented in a factory in only one step.
First, we must observe that the anomaly is not that software progress is so slow but that computer hardware progress is so fast. No other technology since civilization began has seen six orders of magnitude price-performance gain in 30 years.
Coding is “90 percent finished” for half of the total coding time. Debugging is “99 percent complete” most of the time.
The complexity of software is an essential property, not an accidental one. Hence descriptions of a software entity that abstract away its complexity often abstract away its essence.
Study after study shows that the very best designers produce structures that are faster, smaller, simpler, cleaner, and produced with less effort. The differences between the great and the average approach an order of magnitude.
A programming systems product takes about nine times as much effort as the component programs written separately for private use.
My rule of thumb is 1/3 of the schedule for design, 1/6 for coding, 1/4 for component testing, and 1/4 for system testing.
First, my wife, my colleagues, and my editors find me to err far more often in optimism than in pessimism. I am, after all, a programmer by background, and optimism is an occupational disease of our craft.
Because we are uncertain about our scheduling estimates, we often lack the courage to defend them stubbornly against management and customer pressure.
Adding people to a software project increases the total effort necessary in three ways: the work and disruption of repartitioning itself, training the new people, and added intercommunication.
Very good professional programmers are ten times as productive as poor ones, at same training and two-year experience level.
Programming increases goes as a power of program size.
All repairs tend to destroy structure, to increase the entropy and disorder of a system.
The fundamental problem with program maintenance is that fixing a defect has a substantial (20-50 percent) chance of introducing another. So the whole process is two steps forward and one step back.
One must assume that there will be lots of bugs, and plan an orderly procedure for snaking them out.
To achieve conceptual integrity, a design must proceed from one mind or a small group of agreeing minds.
Maintenance cost is strongly affected by the number of users. More users find more bugs.