Facts and Fallacies of Software Engineering - Book Review

I read Facts and Fallacies of Software Engineering and I quite enjoyed it. I enjoyed so much that I wanted a review and wanted to write down the quotes that I took.

The author is very knowledgeable and he knows his stuff, at least you can get the confidence that he knows his stuff. While I was reading the book, at some point, I said out loud “This is my people” the author and the audience. This does not happen very frequently and even when I read software related books.

“This” refers to software people and specifically; engineers that are working in the software industry. These people are the ones that are writing the software, preparing the meal in the kitchen, they know how that meal is made, they know what needs to be done to make it happen. They saw the sweet sweat to make that feature ship.

Most people are saying a lot of things about software. Software is eating the world, software is going to change a bunch of industries, software is revolutionizing how we do business, etc. Software is a relatively new field, there are going to be big opportunities and business people are speculating on this field is not the worst thing in the world. However, what I would like to hear more is from people in the kitchen. Not the people who are selling, not the people who are advertise(market), not the people who invest, not the people who manage. I want to hear people who are preparing the meal. I would like to hear how the preparation process is happening and how that process can be improved. So much for the kitchen analogy.

The book is a very easy read and well separated into various facts and fallacies. So, you can read one-two facts at a time. It is also a great example in the software field to be able to understand the software much better since the author is knowledgeable quite a bit in the area.

However, he has also a lot of biases and fallacies as well. First and foremost, the supporting facts to his point are given in a much more detailed way where he is not very meticulous about counter arguments. Also, some of his supporting facts is either from his personal experience or very “anecdotal”. While he is arguing some of the facts and fallacies are nothing but subjective opinions, he is supporting some of the “facts” in a very similar way.

Even though it has quite a few shortcomings, while reading the book, one can sense that most of the things in the book are learned in the kitchen, which itself is a reason to buy this book.

Software

Maintenance, Maintenance, Maintenance

This is the stage which starts where you push the button to deploy the code into production. And it just never ends. You build features in this stage on top of the existing the codebase, you still need to fix bugs that is in the code, you still need to do a lot of work to be able to make it not break whether to accommodate various software dependencies or to accommodate a change in the downstream service.

This book gives a special importance on the maintenance in the software which is very well deserved. Most of the software engineers spend quite a bit of time in this stage of software development, but this is also the area where most of the time is spent. Technical debt shines in this stage of the software and arguably why this stage requires a large amount of time as well. Legacy code first needs to be read and understood; and this in technical debt is not very easy thing to do.

Audience

When you read the book, you can say that “this is my people” for the audience. Complaints around time estimation and how they are being done by non-engineer teams, how estimation of projects is always wrong in some measure, why projects can fail time after time, everything that an engineer could complain about software projects is here. It feels back in the school only difference, these time, adults are the the ones who are complaining.

Some Good Quotes

  • Good management is more important than good technology. (Al Davis, Principles of Software Development)

  • We claim that people work better when too-tight schedules and too-binding constraints are imposed on them. We deny our programmers even the most fundamental elements of trust and then expect them to trust us in telling them what to do.

  • The prime factor in affecting the reliability of software is in the selection, motivation and management of the personnel who design and maintain it.

  • More than anything else, I would want to know that the person who wrote the software was both highly intelligent, and possessed by an extremely rigorous, almost fanatical desire to make their program work the way it should. Everything else to me is secondary …

  • The hypesters, as it turns out, almost always are nonobjective folks who have something to gain - product sales, high-priced courses, or funding for research projects.

  • Hardware envy: cheaper/better/faster happens over and over again in the hardware world.

  • Many of the software tools put on the figurative shelf and never used, that the term shelfware was invented to describe the phenomenon.

  • Most of our estimates are more like wishes than realistic targets.

  • There is almost always a price to be paid for working toward an unrealistic deadline. That price is most often paid in human terms (reputation, morale, and health, among others), but - as you can see in this story - there is likely a financial price to be paid as well.

  • When upper management fails to listen to such knowledgeable words of warning, software people tend to lose faith and trust in those who are giving them direction. And they also lose a whole lot of motivation.

  • A very strong correlation between level of productivity and feeling of control(when programmers felt in control of their fate, they were much more productive). In other words, control-focused mangement does not necessarily between does not necessarily lead to the best project or even to the most productive one.

  • New kid on the block phenomenon hits us is that we possess all-too-often incurable optimism. It’s as if no one has ever been able to solve the problems we are able to solve, we believe that no new problemis too tough for us to solve.

  • When we believe we will instantly produce software without errors and then find that the error-removal phase often takes more time than systems analysis, design, and coding put together.

  • It is the exception rather than the rule to ifnd a componet that would be truly generalizable across a multiplicity of applications, let alone domains.

  • Screwed together components would be a wonderful way to build software. So would automatic generation of code from a requirements specification. And neither of those, in my view, is ever likely to happen in any meaningful way.

  • Someone building a reusable component is thinking of a particular problem to be solved and trying to determine whether there is some more general problem analogous to this specific one.

  • Reusable component needs to be generalized: it is not enough to show that it solves your problem at hand. It must solve some related problems, problems that may not have been so clearly in mind when the component was being developed.

  • It is amost always a mistake to modify a packaged, vendor-produced software systems.

  • Why is “understanding the existing product” the most dominant and difficult task of software maintenance? (Because there are so many possible correct solution approaches to solving any one problem)

  • Thinking time constituted the intellectual component of the task, and the jotting time constituted the clerical part.

  • Mistake of omission errors: the most persistent software errors - those that escape the testing process and persist into production version of the software - are errors of ommitted logic. Missing requirements result in omitted logic.

  • In a room of full of top software designers, if any two of them agree, that is a majority.

  • For complex processes, optimal design is usually not possible, and we must strive instead for what Simon calls a “satisficing” solution. Satisficing (rather than optimizing) solutions are those that can be seen to satisfy enough of the criteria for a good design that it is worth taking the risk of choosing that approach and proceeding with problem solution, given that an optimal design is likely to be either impossible or not cost-effective to find.

  • Typical software product defeats any attempts to do exhaustive testing. Because of that, testing is an act of compromise, and it is vital to make the proper compromise choices, and it is not surprising that most significant software products are released with errors remaining in them(only the naive expect error-free software)

  • Reviews commonly remove up to 90 percent of known errors from a software product before the first test case is run.

  • In spite of the cries for “egoless programming”, most of us have an emotional and intellectual investment in our work product, one that makes particularly vulnerable when others are reviewing it.

  • Old hardware becomes obsolete, old software goes into production every night.

  • The 60/60 rule: 60 percent of software’s dollar is spent on maintenance, and 60 percent of that maintenance is enhancement. Enhancing old software is, therefore, a big deal.

Seven Attributes for Quality Software

  • Portability: is about creating a software product that is easily moved to another platform.

  • Reliability: is about a software product that does what is’s supposed to do, dependably.

  • Efficiency: is about software product that economizes on both running and space consumption.

  • Usability: is about a software product that is easy and comfortable to use.

  • Testability: is about a software product that is easy to test.

  • Understandability: is about a software product that is easy for maintainer to comprehend.

  • Modifiability: is about a software product that is easy for a maintainer to change.

Life-Cycle of Software

  • Requirements definition nad development, when the “what” of the problem is defined and analyzed

  • Design: when how the problem is to be solved is determined.

  • Programming: when the design is transformed into code that will run on a computer.

  • Due to of errors: error removal is performed.

  • Software is put into production; and maintenance begins.

Facts

  1. The most important factor in software work is not the tools and techniques used by the programmers, but rather the quality of the programmers themselves.

  2. The best programmers are up to 28 times better than the worst programmers, according to “individual differences” research. Given that their pay is never commensurate, they are the biggest bargains in the software field.

  3. Adding people to a late project makes it later.

  4. The working environment has a profound impact on productivity and product quality.

  5. Hype is the plague on the house of software. Most software tool and technique improvements account for about 5 to 35 percent increase in productivity and quality. But at one time or another, most of those same improvements have been claimed by someone to have “order of magnitude” benefits.

  6. Learning a new tool or technique actually lowers programmer productivity and product quality initially. The eventual benefit is achieved only after this learning curve is overcome. Therefore, it is worth adopting new tools and techniques, but only if their value is seen realistically and if patience is used in measuring benefits.

  7. Software developers talk a lot about tools. They evaluate quite a few, buy a fair number, and use practically none.

  8. One of the two most common causes of runaway projects is poor estimation.

  9. Most software estimates are performed at the beginning of the life cycle. This makes sense until we realize that estimates are obtained before the requirements are defined and thus before the problem is understood. Estimation, therefore, usually occurs at the wrong time.

  10. Most software estimates are made either by upper management or by marketing, not by the people who build the software or their managers. Estimation is, therefore, done by the wrong people.

  11. Software estimates are rarely adjusted as the project succeeds. Thus those estimates done at the wrong time by the wrong people are usually not corrected.

  12. Since estimates are so faulty, there is little reason to be concerned when software projects do not meet estimated targets. But everyone is concerned anyway.

  13. There is a disconnect between management and their programmers. In one research study of a project that failed to meet its estimates and was seen by its management as a failure, the technical participants saw it as the most successful project they had ever worked on.

  14. The answer to a feasibility study is almost always “yes”.

  15. Reuse-in-the-small (libraries of subroutines) began nearly 50 years ago and is a well-solved problem.

  16. Reuse-in-the-large (components) remains a mostly unsolved problem, even though everyone agrees it is important and desirable.

  17. Reuse-in-the-large works best in families of related subsystems and thus is domain dependent. This narrows the potential applicability of reuse-in-the-large.

  18. There are two “rules of three” in reuse:

  19. It is three times as difficult to build reusable components as single use components

  20. A reusable component should be tried out in three different applications before it will be sufficiently general to accept into a reuse library.

  21. Modification of reused code is particulary error-prone. If more than 20 to 25 percent of a component is to be revised, it is more efficient and effective to rewrite it from scratch.

  22. Design pattern reuse is one solution to the problems inherent in code reuse.

  23. For every 25 percent increase in problem complexity, there is a 100 percent increase in complexity of software solution. That is not a condition to try to change(even though reducing complexity is always a desirable thing to do) that is the just way it is.

  24. Eighty percent of software work is intellectual. A fair amount is creative. Little of it is clerical.

  25. One of the two most common causes of runaway projects is unstable requirements.(See Fact 8 for other cause)

  26. Requirements errors are the most expensive to fix when found during productioni but the cheapest to fix early in the development.

  27. Missing requirements are the hardest requirements errors to correct.

  28. When moving requirements to design, there is an explosion of “derived requirements” (the requirements for a particular design solution) caused by the complexity of the solution process. The list of these design requirements is often 50 times longer than the list of original requirements.

  29. There is seldom one best design solution to a software problem.

  30. Design is a complex, iterative process. The initial design solution will likely be wrong and certainly not optimal.

  31. Programmers shift from design to coding when the problem is decomposed to a level of “primitives” that the designer has mastered. If the coder is not the same person as the designer, the designer’s primitives are unlikely to match the coder’s primitives, and trouble will result.

  32. COBOL is a very bad language, but all others (for business data processing) are so much worse.

  33. Error removal is the most time consuming phase of the life cycle.

  34. Software that a typical programmer believes to be thoroughly tested and has often had only about 55 to 60 percent of its logic paths executed. Using automated support, such as coverage analyzers, can raise that roughly 85 to 90 percent. It is nearly impossible to test software at the level of 100 percent of its logic paths.

  35. Even if 100 percent test coverage were possible, that is not a sufficient criterion for testing. Roughly 35 percent of software defects emerge from missing logic paths, and another 40 percent from the execution of a unique combination of logic paths. They will not be caught by 100 percent coverage.

  36. It is nearly impossible to do a good job of error removal without tools. Debuggers are commonly used, but others, such as coverage analyzers, are not.

  37. Test automation rarely is. That is, certain testing processes can and should be automated. But there is a lot of the testing activity that cannot be automated.

  38. Programmer-created built-in debug code, preferably optionally included in the object code based on compiler parameters, is an important supplement to testing tools.

  39. Rigorous inspections can remove up to 90 percent of errors from a software product before the first test case is run.

  40. In spite of the benefits of rigorous inspections, they cannot and should not replace testing.

  41. Postdelivery reviews(some call them “retrospectives”) are generally acknowledged to be important, both from the point of view of determining customer satisfaction and from the point of process improvement. But most organizations do not do postdelivery reviews.

  42. Peer reviews are both technical and sociological. Paying attention to one without the other is a recipe for disaster.

  43. Maintenance typically consumes 40 to 80 percent(average, 60 percent) of software costs. Therefore, it is probably the most important life cycle phase of software.

  44. Enhancement is responsible for roughly 60 percent of software maintenance costs. Error correction is roughly 17 percent. Therefore, software maintenance is largely about adding new capability to old software, not fixing it.

  45. Maintenance is a solution, not a problem.

  46. In examining the tasks of software development versus software maintenance, most of the tasks are the same - except for the additional maintenance task of “understanding the existing product”. This task consumes roughly 30 percent of the total maintenance time and is the dominant maintenance activity. Thus, it is possible to claim that maintenance is a more difficult task than development.

  47. Better software engineering development leads to more maintenance, not less.

  48. Quality is a collection of attributes: portability, reliability, efficiency, usability, testability, understandability, and modifiability.

  49. Quality is not user satisfaction, meeting requirements, meeting costs and schedule targets, or reliability.

  50. There are errors that most programmers tend to make.

  51. Errors tend to cluster.

  52. There is no single best approach to software error removal.

  53. Residual errors will always persist. The goal should be to minimize or eliminate severe errors.

  54. Efficiency stems more from good design than from good coding.

  55. High-order language(HOL) code, with appropriate compiler optimizations, can be about 90 percent as efficient as the comparable assembler code. Or even higher, for some complex modern architectures.

  56. There are tradeoffs between size and time optimization. Often, improving one degrades the other.

  57. Many software researchers advocate rather than investigate. As a result, some advocated concepts are worth far less than their advocates believe, and there is a shortage of evaluative research to help determine what the value of such concepts really is.

Fallacies

  • You can’t manage whay you can’t measure.

  • You can manage quality into a software product.

  • Programming can and should be egoless.

  • Tools and techniques: one size fits all.

  • Software needs more methodologies.

  • To estimate cost and schedule, first estimate lines of code.

  • Random test input is a good way to optimize testing

  • Given enough eyeballs, all bugs are shallow.

  • The way to predict future maintenance costs and to make product replacement decisions is to look at past cost data.

  • You teach people how to program by showing them how to write programs.

Reality is the murder of a beautiful theory by a gang of ugly facts.

As reality, software is the murder of a beautiful theory by a gang of ugly facts.