Let design guide, not dictate
Tuesday, May 27th, 2008A good design should be intended to guide implementation, not dictate it, and for good reason as in the real world of software development requirements and systems are far to complex and dynamic in nature to view a technical design as anything more than a basic prescription intended to form the basis of an efficient implementation. Yet far too often many people seem to believe that once a detailed design has been completed and approved implementation should be a breeze; however this is just not a very realistic expectation.
For instance, one of my core job responsibilities is to review technical design documents and provide feedback and direction. This is an iterative process which typically has between 1-3 iterations depending on the complexity of the system. Initially an engineer is given requirements for review; he/she then begins an initial draft of the design and once completed passes it on to me for review. I then review the document and provide feedback where applicable, either via annotations to the document itself or by sitting with the developer, which is by far my preferred process. Should modifications be required the developer will then make revisions as needed. This process is repeated until final design has been approved. At first it may appear as if only a single iteration of design and review would be needed, however more often than not, requirements may not be completely understood during the beginning stages of design, nor are they set in stone so it is very common that a design will need to change during the early stages of a project or even throughout the entire development stage. Once final design has been completed an engineer then begins implementing the design. Theoretically this may appear to be a quite simple process: create a great design which contains as much detail as possible, review it, make revisions and approve it, then just pass it off to any old developer to implement and that’s it, done - wrong!
There are a number of problems to this approach. Below I have outlined the three I feel are most significant and the solutions I have found to address each.
The first problem is that a design which goes into too much detail completely limits or even worse, kills creativity - which in my opinion is the single most important trait a developer can possess, especially when designing. The developer is now merely a typist and will undoubtedly become very bored when implementing the design, especially if it is not even his/her design to begin with! Because of this lack of creativity the final code will ultimately suffer and bugs can be expected. Keeping design on a higher level allows developers to have the creative freedom needed to provide quality implementations and work they can feel is their own.
The second problem is that the more detailed and precise the design the less flexibility there is when requirements change and modifications need to be made to the design and thus implementation. For example, if a design contains very low level details, such as method signatures and other implementation specific details the ability to change the design now becomes increasingly complex and will result in much of the design needing to be reworked significantly. In addition the more detail there is the harder it is to write unit tests against the design as the actual implementation has already been defined. Designs need to be very high level and should not go beyond identifying class names, their responsibilities, relationships and dependencies.
The third problem, which is probably the single most consistent problem I have recognized in my experiences is that far too often developers get caught up in all the details of UML notation and related tools. Again this negates creativity and results in the developer concentrating more on making the design look technically correct rather than concentrating on designing towards a great solution to the problem at hand. In addition this also results in unnecessary time being spent to complete the design, time which could be much better spent on something that produces a better pay off for the project. Now this is not to say that UML shouldn’t be used, actually quite the contrary. I strongly feel that a final design must be in UML as a shared language is needed in order for everyone involved in the design and implementation to easily understand the design. I insist on a technique where developers draw out their design in any way that can be easily understood by them without having to give any thought to anything other than the design itself. Only once the design is finished is the use of Visio or other UML tools to be used.
The above illustrates the three most common design issues I have encountered, most of which pertain to over detailed designs, as well as the approach I take in addressing each. If you have not encountered any of these issues in your own work than that is generally a good sign, however try to keep them in mind when designing as it will pay off in the end. The important thing to keep in mind when designing is to design for flexibility and simplicity. Less is usually more and the KISS principle, especially when applied to software design will always pay off in the end.
