Day 21: Design The Big Picture First
In a previous post I suggested that optimizing a program should only be done with knowledge of how time is spent. The reason is that we usually don’t know where a program is spending most of its time. This results in a lot of energy being wasted in optimizing what doesn’t need improvement.
Similarly, a lot of design effort is spent on areas of the system that don’t require so many resources. Many details are introduced very early in the process, when they may be more a hindrance than a help. The main reason why this happens is that we frequently design systems without thinking of the big picture first.
Writing code is hard. No matter how much experience you have, there is always some aspect of the problem that you don’t understand completely. And these are the problems that will bite you when you less expect.
Consider the architecture first. What are the main functions of the system? How these functions could be divided into higher level elements, such as services, applications, and libraries?
Once you determine how the system is functionally and physically defined, you can start to look at the structural organization of each element, such as major classes, functions, and libraries.
This physical design planning is essential to determine the best way for the system to develop and evolve as necessary. There are few things so frustrating as creating software that has bad architecture. Even though each piece might have been created successfully, the pieces don’t fit together and whole system becomes a heavy burden to maintain and evolve.
Design of Components
The way components interact in software application is also of great importance. Subsystems should have sane dependencies, so that they are easy to maintain and even to be interchanged if necessary.
For instance, a big problem that occurs in the design of components is cyclical dependencies. When two modules of the program need to know about each other, this creates an undesired coupling between components that is hard to break.
A practical example would be a music application in which the MP3 code depends on the recording code, and vice versa. In such a situation it is hard to create another application that deals only with MP3, because the recording code wants to be part of it. This is not only undesirable for the whole application, but can make it much harder to maintain each of the individual components.
A few design patterns offer help in this regard. For example, the MVC pattern is an object oriented design that was created to avoid the problem of coupling between the graphical interface and the application model. It is possible to find modern implementations of MVC from desktop GUI libraries to web frameworks. Even if you don’t have access to an MVC library, it is possible to use the design pattern when creating your own code in order to avoid this insidious type of dependency.
Conclusion
Lots of developers think that creating code is just a matter of putting together a set of classes or functions to do the job. This might work for simple applications, but most systems will require a thoughtful and maintainable design.
The best approach is to look at the big picture and design how the system is supposed to work. Think about the major components and how they interact. Make sure that you understand the interaction between components. Finally, look at the source code and how it should be organized. It is a bit of initial work that can solve a lot of problems in the future.
References
[1] Image credit: commons.wikimedia.org