Saturday, January 31, 2015

Software Design Principles

In software design, there is a direct, strong, and undeniable correlation between principles and quality.  These principles guide us to create good designs which become good code which becomes good software.  It is absolutely worth your time to understand these principles and remember them.
There are many more principles than these, but the ones listed here are solid, proven, fairly well known, and will guide you to create strong designs.

The Single Responsibility Principle says that each class and each function should have one single, specific, and well-defined purpose, and it should never do anything that is unrelated to its purpose.  This principle is essentially just a reminder of the importance of cohesion.

The Hollywood Principle says, “Don’t call us, we’ll call you.”  What it means is that some classes should serve a high-level purpose and be the ones that drive processes, while others should simply perform the low-level tasks and nothing more.  High level classes should invoke methods of lower-level classes, but never vice versa.

The Principle of Least knowledge says, “Only talk to your immediate friends.”  When diagramming your design in a UML class diagram, each class should only invoke methods of classes that are directly connected to it.  This provides many advantages; one of the most significant being that it greatly reduces coupling.

Occam’s Razor is a well-known scientific principle that we can modify slightly to fit the purpose of software design.  It says if two different designs are both satisfactory, then the simpler one is better.

The Open/Closed Principle says that classes should be open to extension but closed to modification.  The idea is that code should be designed so that new functionality can be added without changing the existing, working code.

The Liskov Substitution Principle says that if you can design your classes to depend on abstract classes and interfaces, then any subclass of those can be substituted in later regardless of how it implements the functionality behind the scenes.

Favor composition over inheritance.  In many (but not all) cases, using composition for code reuse works just as well as using inheritance.  Composition has the advantage of looser coupling, improves reusability, simplifies testing and maintenance, and provides numerous other benefits.

Separate the aspects that vary from the aspects that stay the same.  If your design must work within several different contexts, identify what is different between those contexts and what stays the same.  If you can separate the part that stays the same, then you only need to worry about adapting the part that differs.

No comments:

Post a Comment