I'm currently reading a book about Software Engineering. I'm not to impressed about most of the content, since most of it is rather irrelevant for modern software development. But among other things the section about specifications caught my interest. The author considers a precise and complete specification tremendous important. His reasons are:
- The specification is important for testing, because otherwise testers, developers (and possibly everybody else in the area) will fight about what kind of behavior is to be considered a bug, and what is a feature.
- The specification is important if a system is to be replaced. For such a replacement there is an implicit requirement: "If we didn't explicitly asked to change a behavior, the new system should do the same as the old one". If you don't have a correct and complete specification your only option is to basically reengineer the system, which will cost a lot of time and money (and is no fun at all)
Sounds reasonable right? Well yes and no. It's like planning a manned space mission to the center of the milky way and starting with: "First we have to find the holy grail, so the astronauts can drink from it in order to become immortal. If we don't do that the astronauts will be dead long before they arrive at their destination." Yep, they will be dead. Problem is: There is no holy grail. So a better plan might be to include female and male astronauts that can make sure there are still astronauts alive at the destination.
Requirements change. Replacing a system after 5, 10 or even 20 years of service and hoping, the specification from back then is more then a first hint on what the system does and what it is used for, is just stupid.
IF you have a precise and complete specification it should be easy to decide if a certain behavior of a program is a bug or a feature. It doesn't solve the issue though that who ever wrote the specification in the first go has no way to determine what the user actually needs and want, because this will change as soon as the user sees some working software.
So repeat after me: "There is no such thing as a complete and correct specification of a non trivial piece of software, except the software itself."
Code is the only way suitable for specification of software projects that is precise and (potentially) readable enough to be used as a specification.
It is always precise in the sense, that whatever is in the source code is what gets executed, so it is a precise description of what the software does. It is always up to date. All changes are reflected there, because there is simply no other way.
The part about being readable obviously varies a lot. Most code is not understandable by a normal customer. I have seen lots of code (partially my own) that obviously wasn't understood by anybody at any given point in time. But there is hope. With the practices explained in the nook Clean Code we are able to keep code clean on the detailed level. Well written code is actually quite easily understood by a competent developer. On a higher level of abstraction there exists the concept of specification by example, i.e. the idea that for every requirement a set of examples gets created. These examples have many benefits over other kinds of specification:
- They can be made much more precise then normal text can ever be.
- They can be made executable by tools like FitNesse so they actually serve as tests.
- They are easily understood by domain experts, developers, testers and everybody else involved.
Basically they are the ultimate form of clean code: Code that is so clean, it can be understood by domain experts and thereby can be used to specify and discuss functionality.
You'll still need some prose to provide some background and to explain what the examples are about, but these now become comments inside code. While such comments are prone to become stale, their chance to stay fresh and updated are much better then specification stored in a completely separate document.
Yes we need a specification in the sense that the developer who does some coding and the tester who does some testing need to understand the requirements. But classical forms of specifications in separate documents are a crutch and a bad and obsolete one. Go for code. Go for clean code understandable by everybody involved. Go for clean code on every level from specification to detailed implementation.