My objective is to produce the highest quality of product at a predictable cost. I achieve that by employing the best design process practices.
The largest source of cost overruns in any project is changes to the design during the process of development. This is almost always a result of a failure to achieve an informed agreement to the design. I always put a superior effort into communicating my understanding of the client's requirements through a well-structured functional specification. I not only see this as a high priority, but I actually enjoy creating this formal documentation and negotiating through it to agreement by the customer to the proposed design.
Any worthwhile product must be the creation of a team of developers who all have a clear view of the objective and of their individual roles in achieving that objective. This requires a detailed analysis of the components into which the total product can be divided, and the relationship of each component to the other components. This is most effectively achieved through the application of sound design principles and methodologies. The result of this phase of development is a clear design specification.
Given a clear design specification the translation to actual working code is a largely mechanical process for any competent group of implementers. Astonishingly large quantities of clean, well-structured, code can be achieved in short order because the designers do not need to waste time solving design problems in the middle of coding. The use of object oriented programming tools, such as C++ or Java, combined with a sound underlying design for example through the use of design patterns, inevitably means that the majority of implementation errors can be caught automatically during the compile phase.
Once the development team has completed a first implementation of the code it is very useful to take the time to formally review the code. This is called a code inspection. Not only does this step catch most areas where the programmer has misunderstood the specification, but it also provides a great opportunity for passing on knowledge about the software tools and environment, and helps to reduce maintenance costs in the long term by ensuring that code complies with departmental norms for coding style.
If the preceding steps have been followed diligently there will be very few flaws in the code. The purpose of the testing phase is primarily, therefore, to ensure that the implementation in fact complies with the functional specification, and therefore meets the requirements of the customer. At this stage it is worthwhile to implement automated conformance scripts that can be passed on to the team responsible for verifying the consistency of the entire release package to which the product belongs.
I have always followed this sort of methodology, even before many of these techniques became industry standards. On my very first job, back in the days of punch-cards, I was kidded because I filled in the coding sheets in ink, rather than the pencil that most programmers used because it permitted them to change their minds before they handed the sheets in to the data entry department. But the fact was that before I laid pen to paper I had already worked out the implementation so carefully that there was no need to amend the code. Similarly on the first project I contributed to at Nortel I assumed responsibility for the specification documents and also for the most technically challenging portions of the code. I contributed 30,000 lines of code (OK 12,000 lines of code and 18,000 lines of comments; I love comments) to that project. That was in 1986. 13 years later not a single bug had ever been reported in that code by a customer. Moreover that code was so well structured that several significant enhancements to it slid in easily with no change to the underlying design.