Learn Architecting .NET Application – Design Principles

I have recently read the book  Microsoft .NET – Architecting Applications for the Enterprise (Developer Reference).  The book was published in 2008 but the architecture principles and patterns explained in this book are still quite helpful for us in today’s .Net software development.  If you dont’ want to read a really-long-book, I strongly recommend you to watch the Pluralsight course Architecting Applications for the Real World in .NET.

The immediate outcome of these learning is that i have now better understanding of existing system i am working on and start to have a better thought about the code i am writing from architecture’s point view.

Here are some key takeways about design principles that really inspire me:

A system designed to achieve low coupling and high cohesion generally meets the requirements of high readability, maintainability, easy testing and good reuse.

Coupling measures the level of dependency existing between two software modules such as classes, functions or libraries. More specifically, two modules, A and B are said to be coupled when it turns out that you have to make changes to B every time you make any change to A. Low coupling doesn’t mean modules should be completely isolated from each other. They are allowed to communicate with each other but through set of well-defined and stable interfaces. Each module should be able to work without knowing another module’s internal implementation.

Cohesion measures the distance between the logic expressed by various methods on a class, various functions in a library and various actions accomplished by a method. High cohesion means the a module should have well-defined responsibility and focus on what it should do instead of doing many things that have nothing in common. Single responsiblity Principle is a good example of high cohesion.

A good object-oriented design, in fact, is characterized by low coupling and high cohesion, which means that self-contained objects(high cohesion) are interacting with other objects through a stable interface (low coupling).

A principle that is helpful to achieving high cohesion and low coupling is Separation of Concerns(SoC).

SoC is all about breaking the system into distinct and possibly non-overlapping features. Each feature you want in the system represents  a concern and an aspect of the system. It can be achieved by using modular code and making heave use of information hiding.

The concept of SoC has been applied everywhere. In OOP programming languages like C# and Java, you separate concerns using classes. In Service-Oriented Architecture, you use services to separate concerns. Layered architectures are based on SoC. Object/Relational Mapping tool (O/RM) can be used to separate persistence from the domain models. Model-View-Controller(MVC) is also a typical application of SoC.

OOD principle NO 1: Program to an interface, not an implementation.

Interface represents “What” to do not “How” to do it. When class dependencies are based on interface rather than an implementation, you minimized coupling between classes to the smallest possible set of functions which are those well-defined in the interface.

OOD principle NO2: Favor object composition over class inheritance.

Object composition and class inheritance are the two ways to achieve software reusability. On composition, a class, which desire to use functionality of an existing class, doesn’t inherit, instead it holds a reference of that class in a member variable (internal object), that’s why the name composition. Inheritance and composition relationships are also referred as IS-A and HAS-A relationships.With composition, changes to the composite object doesn’t affect the internal object. Likewise, changes to the internal object don’t affect the outmost containers as long as there are no changes to the public interface.

Basic principles such as low coupling, high cohesion(along with the single responsibility principle), separation of concerns, plus the first two principles of OOD give us enough guidance about how to design a software application