There is a process to be followed when designing or redesigning software systems, whether that process is the same for every system or not. There are just some things that need to happen that will help solidify the product and get some kind of stability in the software and in the customer’s confidence. This is a general overview, if for no other purpose than to remind myself of it.
1. You must have a problem. If not, what the hell are you doing? Software tells computers to solve problems in most cases. In all others, the problem is that the programmer doesn’t know something and is moving through a project to learn an aspect of development. Those learning projects are the hardest to get through sometimes. Anyway, either you or your customer has a problem that can be solved with computers, and that’s why you’re here.
2. Gather requirements. This should always be the next step, and it should always be very early – before you pick a platform, language, development team, or flavor of Jolt, gather the requirements from the customer and start hacking at the root of the problem. This is the most important step, because it is from here you will begin to draft your agreement with the customer about the scope of the project. Requirements gathering should be done as diligently as possible to ensure you and your team know the scope or constraints of the solution you’re developing.
3. The agreement. This is where you hammer out exactly what problem you’ll solve and every aspect of the solution. This statement of scope will define the limits of the product and the customer should be told that they cannot add anything once an agreement is reached. Imagine getting to the end of a nine-month project and the customer changes the requirements… It will waste time and money, and WAY more than you might think at first. You’ll never really know what it’s like to have an insatiable desire to strangle someone until you have a customer trying to chisel something else into the project during testing. Make sure everything is in the design to begin with, and work hard until it’s all agreed upon. It’s much cheaper to work something in at the beginning than to wedge it in at the end. Just ask Microsoft.
4. The Design. Once the requirements and scope have been determined and agreed upon, it’s time to begin the specification for the software system. This includes a functional design specification and a software design specification. The two are closely related, but still distinct. A functional design specification is a document describing what functions the system performs at a high level. Since you’re building the software from the ground up, a system that performs these functions likely doesn’t exist. If it did, we might buy that one instead of building this one. So – given its uniqueness, we need to define its functions and general workflow. A software design specification takes those functions defined in the functional spec and describes them in a way the code monkeys can understand. The software design specification takes into account the limitations and nuances of programming languages and how computers work and applies that to the problem at hand to perform the function necessary in each part of the system. This is the nitty-gritty spec that should describe everything down to the last detail so that when it’s handed over to a programming team, there will be no questions.
5. Code. But there will always be questions, so be ready. During the implementation phase (the part where code is written and actually run on a computer), if the system is large enough there will be many iterations and backs-and-forths about minute details ranging from data types to interface colors. Again, most of the details should be in the software design specification but, well, we’re human. It always happens. Only when the machines start writing perfect code can we relax about this phase.
6. Test. Often the most painful phase of a software project is the testing phase. If it’s not painful, you’re not doing it right. In my opinion, most of the time testing teams are needed, not just a single software testing engineer. You have to throw absolutely everything you have at the code to see how bulletproof it is. Testing tools, load generators, keyboard monkeys, children, everything. Also, continual testing is necessary for ongoing maintenance to make sure newly-discovered vulnerabilities are being plugged and tested against in each iteration of deployment. In short, leave no stone un-turned and never let a place get dusty. Be very diligent at all times. Software testers are not temps.
7. Document. Every large team has turnover, no matter what the rate is. People quit, die, get offers from their dream company, have mental breakdowns, etc. In these cases where you’ve got a new person replacing a project veteran, documentation is essential to reducing wasted time. First, the functional and software design specs should be up-to-date (and also interesting enough not to put the reader to sleep) and ready for anyone to review. Each developer team member should also keep a work log of some sort to keep track of those small daily decisions he or she makes during the coding phase; the next guy may not know why you did what you did.
In conclusion, I can’t say that these perspectives on the development process are always necessary with every software development project, but some aspect of these steps will come in to play in everything that isn’t a two-line script. Whether anything is documented during the conception or planning stages is irrelevant; those things happen whether you write them down or not. Each project has a beginning, a development, and (it is hoped) a use afterwards in the real world.
No matter what development methodology is used, design, testing, and documentation are all of equal importance. If you’re managing your software project by the seat of your pants, get a grip on things and start documenting. Stop lying to yourself about that timeline and conjure up some real figures.
I’ll end with some books I recommend:
Joel Spolsky, Joel on Software: And on Diverse and Occasionally Related Matters That Will Prove of Interest to Software Developers, Designers, and Managers, and to Those Who, Whether by Good Fortune or Ill Luck, Work with Them in Some Capacity
Steve McConnell, Rapid Development: Taming Wild Software Schedules
and Code Complete: A Practical Handbook of Software Construction, Second Edition
Andrew Hunt and David Thomas, The Pragmatic Programmer: From Journeyman to Master