Random Thoughts on Software Design
Three months ago, I wrote an article Random Thoughts on IT Automation. I think it’s a pretty good style for capturing ideas without worrying much about content organization and flow. So I decide to use it again on software design which I have been practicing and thinking for many years.
Lost VMs or Containers? Too Many Consoles? Too Slow GUI? Time to learn how to "Google" and manage your VMware and clouds in a fast and secure HTML5 App.
• A good software design starts from the problems it tries to address, not the frameworks/APIs it can rely on.
• Software design is a dynamic process. It changes over time.
• The biggest value of a software design is to force the team to think through the critical decisions, and bring everyone on same page.
• A design committee only improves a design when an open minded member can make final calls. It turns out not true in reality, so most designs by committee are bad.
• A software design is not part of final deliverables. Stop when it’s enough for implementation.
Principles and Tools
• Design principles are easy, but how to apply them on a right project in a right way is hard.
• Apply software design patterns only when you have to. In most cases, design patterns are liabilities due to misuse or over use.
• A good metaphor simplifies a design and makes it easier to learn and follow.
• A basic goal of software design is to divide a complex problem to smaller and more manageable components/modules.
• Not all frameworks/APIs are created equal. Use them only when it justifies the effort to learn and the cost of inclusion and maintenance. Be conservative and selective!
• UML is nice, but not a must. Don’t try to standardize on design languages.
• If you can generate code with a model, then the time to build the model is most likely longer than to write code directly.
• One way dependency is good because it means code reuse; two way dependency is bad because it means two modules are still tightly coupled.
• Only software code fully and exactly describes the behavior of a system. A design does not.
• Unlike code, a design is not testable with strict and consistent procedures.
• Work hard for simple designs, not smart designs.
• A good design must be consistent in concepts, terminologies, structure, interfaces, and protocols.
• Be realistic on a design: don’t expect it to solve all possible problems, but existing and potential problems; don’t expect it to be all correct, but to change over time; don’t expect it to cover all aspects, but to improve over time; don’t expect it to be perfect, but consistent and simple.
• A design is to guide the implementation afterwards. If it’s not understood by all stakeholders, its value is compromised significantly. Therefore simplicity is a must.
• Don’t go extreme on design principles and guidelines. Nothing is absolutely correct in all contexts.
• Whoever designs an architecture should follow through its implementation, and be held accountable for its success or failure.
• A good software architect must have gone through a full cycle of a project including maintenance phase in which the results of many design decisions finally show up. This first-hand experience cannot be learned anywhere else.
• A good architect should be a good coder, at least in early days of her career. Without good sense of implementation, an architect may come up with nice diagrams but not implementable.
• Small projects share almost the same design principles as large projects, therefore are good places to accumulate architecture experiences. So are open source projects.
• The audiences of software designs are human beings and human beings only.