3 Jan, 2019 Update: I see this posting appears to get a lot of traffic from those looking for Jim Heumann’s article on good requirements. The link from when this article was originally published is no longer good, however you can read the article as it appeared on IBM’s website in July 2004 in PDF form here. Note: You will need to scroll to locate the article as this PDF is The Rational Edge in its entirety. The article is on page 24 of 150.
Note: This post is for an assignment here at Drexel. You’re welcome to read it, but it’s a departure from the usual programming.
Jim Heumann’s article “Writing good requirements is a lot like good code” is a brilliant read (
which you can do here). If you’ve ever had to program or design a system for someone, especially in a professional environment, you may already be familiar with some of Heumann’s points. If you’ve never, well, hopefully your first experience will be a smooth one.
Good requirements and good code go hand-in-hand. It’s very difficult to write code for a system when the requirements you’ve been given are unclear and/or vague. There is also a very good chance your code will require a painful amount of revisions – sometimes to the extent of a full re-write. If you don’t have a clear set of requirements for a system, don’t start building it. Trust me, it will save you a significant amount of trouble down the road.
When you meet with the person who you’re building the system for, for the love of humanity, take notes. If something is unclear, keeping asking follow-up questions until it becomes clear. Beware of what are actually two separate requirements being grouped as one. For example, instead of:
- The system shall support the most recent version of OS X and later openSUSE
Break it in to:
- The system shall support the latest version of OS X
- The system shall support the latest version of openSUSE in a later version
However, even those requirements could be better. Why?
“Later” is vague. When is “later”? The next version? Is that the next minor or major version? Is it next year? By the end of the year? Give it a firm date. It will keep everyone involved accountable and should give you a reminder your code will need to support another system. It might be a good idea to comment your code to account for that now.
Speaking of comments, code should have them. They don’t make more code ugly nor are they a waste of space. They will [hopefully] keep whoever picks up your code after you sane. Writing code for a system without existing good code is quite similar to the experience you’ll have trying to design a system without good requirements. $x is a terrible variable for code. Even if it’s clear in your code that $x is a counter, take the time to actually call it $counter. Better yet, what is it a counter for? $uploadretries is even better.
Now, let’s put that together with a well written requirement:
The system shall retry a file upload a maximum of five times.
while $uploadretries -lt $maxretries
Now, what if the requirement was:
The system shall retry a failed upload.
Yes, you can write code to listen for a failed upload because of a server timeout, but do you really want a file retry to keeping going until the server crashes from a stuck process? OK, maybe that is a bit extreme, but I hope that illustrates my point.
So, in short, good code comes from good requirements. Better code comes from being able to understand the original code. The best code comes from good requirements, code with logical variable names, and comments that document what that code is doing.