What’s the Hard Part of Software Development, Anyway?
By Kal Toth, associate professor, Portland State University
In ’The Mythical Man-Month,’ Fred Brooks said, “I believe the hard part of building software to be the specification, design, and testing of this conceptual construct, not the labor of representing it and testing the fidelity of the representation.” So why do so many software developers devote so much of their time on the coding and testing aspects?
Many developers have told me that adding new features and maintaining software is very tough work indeed. But they say that this is mainly because the documentation is so poor. Doesn’t this make you wonder why the requirements and design specifications are not better?
The importance of defining requirements Increasingly, developers recognize that they need to work closely with their customers and users. They do this partly by writing brief user stories designed to meet perceived needs and satisfy customer expectations. They work closely with customers and users – embracing change as they should. They are prepared to re-factor - as often as necessary - and will throw away chunks of brittle code to get closer to what is needed and wanted. This implies that they are also prepared to invest in, and then throw away, chunks of their tests and efforts put into testing.
All this makes you wonder how much of the throw away re-factoring, coding, and testing efforts could be prevented by understanding more about the scope, structure, and dependencies of the requirements and the design. This begs the question: “What’s the trade-off between synthesis and experimentation?” Another way to put this is: “How much analysis and modeling should be done versus iterative prototyping and evaluation?”
I’ve also heard software engineers say that the hardest part is getting the right skills, training their developers properly, estimating the software tasks, and managing the work to meet schedules and cost objectives. But they often miss the linkage of these activities with requirements and design development. Without valid requirements and sound designs how can they arrive at solid estimates, produce good plans, or assess what resources, competencies, and training will be needed? You might hire or develop the wrong skill sets and competencies to tackle the problem at hand, and not give yourself any markers to assess whether you are going in a good or bad direction – possibly until it’s too late.
Validation key in spite of difficulties All this seems to motivate us to take a closer look at what Fred Brooks said. When he said "testing of the conceptual construct" it might have been clearer or more obvious if he had used the words "validation" or "verification" instead of "testing." This is because software engineers today recognize that they should seek out and invest time in discovering what users and customers really want, that is, validate the requirements – at least, to assess overall scope, critical dependencies, and priorities. Similarly, they will want to be confident that their design will lead to the desired system behaviors and at the same time will tend to accommodate change without being fragile (break). This seems to be true whether they follow an agile approach, or some more rigorous software development process.
Of course, there are many challenges when trying to get requirements and designs "right." The user may prefer narrative descriptions, but such descriptions can be ambiguous with lots of gaps and missing dependencies. Developers meanwhile, prefer more structured descriptions while many users are typically not familiar with such approaches and therefore can’t work with them. No one language, model, or tool seems to satisfy everyone involved. And, of course, even under the best of circumstances, requirements development and design synthesis are not trivial tasks.
Devoting resources in early stages And we can’t forget about what happens downstream, in later development iterations and after system delivery. If we do a bad job of the requirements and the design work, we will produce shoddy documentation - shooting ourselves in the foot by making subsequent development and maintenance work that much harder – for both ourselves and our unfortunate maintenance engineers. And all this reinforces why estimating and planning are so hard to do, why it’s not easy to know who to train or what training to give them, and why lifecycle costs and schedules are so easily and frequently blown. You would think that this flow of logic would help us convince our own teammates and managers to devote adequate resources and schedules in early stages of development to contain costs in later development and maintenance phases (“ah, if it was that easy”).
In summary, requirements are hard to get right without devoting valuable time and effort working closely with users and customers. Often we don't have enough of this, but if we don't invest time in this aspect, we will spend a lot more of our time in rework, throw-away code, and testing. Producing an architecture that is stable yet malleable - that is simple enough to maintain yet extensible for future requirements - is certainly not an easy matter either. Also, efficient and effective testing should be driven by well-formed requirements and sound design – even though they may be incomplete at any given moment. Otherwise we are not really validating or verifying anything in particular. To get these processes to work, of course, we need excellent communications with users, customers, management, and other team members. And corresponding skills and competencies are a must.
Knowing the truth – and selling it My take-way is this: I believe Fred Brooks was right - the hard part is indeed the requirements and the design work. We should devote just enough time and better strategies and processes to develop well-articulated requirements and sound designs – else we are bound to be disappointed by other aspects of our software engineering process. But on second thought, the hard part may actually be selling our teammates and managers that all this is true.
About the author Kal Toth, associate professor in the Portland State University department of computer science, is director of the Oregon Master of Software Engineering (OMSE) program. He holds a Ph.D. from Carleton University (in electrical engineering and computer systems) and teaches several core OMSE courses. He can be contacted at ktoth@omse.pdx.edu; see http://www.cs.pdx.edu/~ktoth/.
|