Monday, November 15, 2010

[Tutorial] S.O.L.I.D. quality code in C#
Part6: Dependency Inversion Principle (DIP)

In most of the applications high level modules are directly linked to low level modules (in other words are dependent on them). High level modules contain most of the time complex logic whereas low level modules serve for basic and primary operations. It is evident that this may lead to dependency problems between those modules.

An application that shows this problem could be structured like this: the Presentation Layer is dependent on the Business Layer which itself is dependant on the Data Layer.

Fig8_DIP_Before

In this layer design, modifications to low level modules force modifications to high level modules that are dependant on them. This leads to high level modules which can not be reused in different technical contexts.

The Dependency Inversion Principle (DIP) therefore explains that high level modules must not depend on low level modules. Both of them have to depend on abstractions. Furthermore abstractions must not depend on details but instead details have to depend on abstractions.

The underlying concept is that abstractions serve as links between high level and low level modules. Abstraction are most of the time expressed via interfaces but the Factory Design Pattern may also be used.

After having applied the principle, the class in the following example is completely independent from other classes, all references being expressed via interfaces.

DIP_After

In the next example, which is based on the Factory Pattern, the class ValidationManagerFactory is used to resolve all dependencies. It associates an object that is implementing the IValidatable interface with an object of type ValidationManager.

DIP_After2

The introduction of interfaces allows the inversion of dependencies, which leads in the layers example to layers that are completely independent from each other.

Fig9_DIP_After

To sum it up, the Dependency Inversion Principle (DIP) provides a high level of flexibility because modules really get reusable easily. All rigid links that may exist between modules are broken up. But by adding a higher level of abstraction, the code gets more complex to understand and to maintain. So this principle must be applied with caution.


Share/Save/Bookmark

Sunday, November 14, 2010

[Tutorial] S.O.L.I.D. quality code in C#
Part5: Interface Segregation Principle (ISP)

This principle demands that clients should not be forced to depend on interfaces they do not use. An entity (class, service, …) is client of an interface, if it uses a class that implements the interface.

Applying this principle is fairly easy. A similar methodology to the one already used in the Single Responsibility Principle (SRP) must be applied. When developing services, it is often necessary to have classes with multiple responsibilities. The Interface Segregation Principle (ISP) permits to limit class coupling between the different classes in this case.

In the following example the class BusinessObject has multiple responsibilities (implements multiple functional groups) like creation, update, validation and deletion.

Fig6_ISP_Before

ValidationManager_Before

PersistManager_Before

Please note the usage of the interface IBusinessObject instead of the class BusinessObject. This approach is called Interface-Based Programming. It allows programming against interfaces instead of concrete classes. Thus, all classes implementing the interfaces required by those functions can be passed as parameters to them. This already provides some degree of independency, but there are still flaws in this class design.

Each client only uses some aspects of the defined interface:

  • The ValidationManager class only uses methods concerning validation
  • The PersistManager class only uses methods concerning persistence

Modifications of methods concerning the validation imply modifications to the whole interface IBusinessObject and indirectly to the PersistManager class. Even though the PersistManager class does not even use those methods !!

We need to find a solution to achieve that different clients only depend on functionality and access methods that they really use.

The first step consists of regrouping all methods that belong to the same functional group in specialized interfaces. Similar to what we already did for the Single Responsibility Principle (SRP) only this time with specialized interfaces as output.

The interface IBusinessObject is separated into two more specialized interfaces IPersistable and IValidatable. It then inherits from those newly created interfaces.

Fig7_ISP_After

Now it is possible to use the different functionalities Persistence and Validation separately as well as using both at the same time. Modifications can be done without any impact between those two functional groups, they evolve independently from each other.

The next step is to replace the current usage of the interface IBusinessObject  with the specialized interfaces IPersistable and IValidatable where applicable.

ValidationManager_After

PersistManager_After

To conclude I would like to underline that in terms of decoupling multiple specialized interfaces are better that one big global interface that contains everything. This approach can also be applied to abstract classes since they might somewhat be considered as interfaces.


Share/Save/Bookmark

Wednesday, November 10, 2010

[Tutorial] S.O.L.I.D. quality code in C#
Part4: Liskov Substitution Principle (LSP)

This principle is complementary to the Open Closed Principle (OCP). It suggests that methods which use a certain class must be able to use its derived classes without even knowing them - a base class must be substitutable by its derived classes, without the necessity of changing any code in the method using it.

There are two violations of this principle: one more conceptual and the other more functional.

The conceptual violation is most of the time easy to detect because it violates the Open Closed Principle (OCP) at the same time. It consists of determining the concrete types of objects to do the adapted treatment in methods. Verifying concrete types or using casts may indicate this violation.

The following code example shows such a case :

LSP_Code_Before

In this example the PrintShapeArea(…) method needs to know the concrete type of the passed object for being able to call the adapted method which returns the correct shape area.

When a new shape type needs to be added, the PrintShapeArea(…) method needs to be modified (violation of OCP). Furthermore object that are used in this context get tightly coupled to the class that contains the PrintShapeArea(…) method.

To prevent this kind of violation the usage of cast, is, as and GetType (working with object types) must be avoided at a maximum.

A good solution is to apply the Open Closed Principle (OCP) as already explained. If we take the same class design from last time, we need to add a GetArea(…) method to the abstract base class Shape. The derived classes need to override this method with the correct shape area calculation.

Fig5_LSP_After

The PrintShapeArea(…) method can now be simplified and is now able to handle all derived classes transparently without knowing them. The base class and its derived classes get substitutable.

LSP_Code_After

The functional violation is much harder to find because it is not due to an error in class design but a modification of internal behavior. Methods may expect certain behaviors of classes they use. Derived classes may change this behavior and the results of operations may differ from the expected results.

The solution to this problem is the Design By Contract approach. This approach assures that functional constraints are respected all the time. It assures that the initial behavior stays the same and that objects always have the correct states.

There are three types of contracts:

  • pre-conditions: constraints and state before treatment
  • post-conditions: constraints and state after treatment
  • invariants: concerned objects must not change during treatment

The necessary classes and methods for the Design By Contract approach are already integrated in .NET Framework 4.0 in the CodeContracts namespace System.Diagnostics.Contracts. But they can easily be added in older versions of.NET.


Share/Save/Bookmark

Monday, November 8, 2010

[Tutorial] S.O.L.I.D. quality code in C#
Part3: Open Closed Principle (OCP)

The Open Closed Principle says that all software entities (like classes and methods) must be open for extension but closed for modification. This sounds odd, because those two rules seem to be contradictory. This article shows how to combine them and how to make your source code even more extensible and maintainable.

So how can a class or method at the same time be open for extension but closed for modification ?

A quick answer is : leave existing code unchanged and allow for extensions only by adding new code. This minimizes at the same time the possibility of regressions, behavior changes and bugs. The application gets more robust and provides a higher level of maintainability. Extension can be done without worrying about the overall stability of the application. All very good things !!!

But the code needs to be correctly structured to achieve this goal. Lets look an example, which shows the principle in action. In this example we start from an implementation that does not respect the Open Closed Principle. Then I apply the principle and you will see how the quality of the code will be ameliorated.

The current implementation contains a single class Shape with a property called ShapeType (possible values Square and Circle).

Fig3_OCP_Before

Furthermore, the application contains the method DrawAllShapes(…), that displays the different shapes on the screen.

Code_OCP

This approach has a major flaw: if new shapes are added, then existing code needs to be changed (ShapeType, DrawAllShapes, etc..). This makes the code hard to understand, to extend and to maintain over time.

So what could be the solution in this case ? In object oriented programming we know the concept of inheritance, which should be applied to avoid the necessity to change existing code.

The complete class design must be changed !

A new abstract class Shape with an abstract method Draw(…) should be created. Then different classes for each shape type, that inherit from the abstract Shape class, need to be defined. They contain the specific code that serves for the display on the screen.

Fig4_OCP_After

The DrawAllShapes(…) method must now be adapted and simplified in the last step. It should only contain the call to the Draw(…) method of objects that are treated.

Code_OCP_After

If you now get the business need to add a new shape type, you only need to create a new class that inherits from the abstract class and implement the special Draw behavior. So extensions become very easy to do. And you do not touch the existing structure anymore (or at least only in very rare cases).

When respecting this principle, your code gets correctly encapsulated, easily reusable and much simpler to maintain.


Share/Save/Bookmark

Sunday, November 7, 2010

[Tutorial] S.O.L.I.D. quality code in C#
Part2: Single Responsibility Principle (SRP)

This is the first principle that I want to show you that will help you to create code that is much less coupled. Code based on this principle becomes much easier to maintain, to evolve and to understand.

Most developers have the tendency to put too much functionality into a single class. Sometimes this is due to bad design, sometimes this is due to the extension of existing code.

Behaviors that should be independent are put together. Those behaviors get tightly coupled and dependant on each other. Changes to a single behavior might impact the other parts of the class (other behaviors).

This may lead to regressions and problems when code needs to be maintained or extended.

The Single Responsibility Principles explains that a class should only have one and a single responsibility. It should serve for only one purpose. Behaviors that belong together must be encapsulated in a single class. But behaviors that are independent from each other must be located in different classes.

When developing new code (or when extending existing code) there needs to be a first phase of conception and design. Within this phase an unordered list of all behaviors and methods is generated, necessary to fulfill the needs of the application (or describing the extensions).

Based on this list the developer creates the class model. Each class generated has a single responsibility. He takes each of the entries in the list and either affects them to existing classes or creates new classes (if the responsibility is not yet covered).

When looking at the following (very simple) example it becomes clear what needs to be done.

Fig1_SRP_Before

The class Modem has more than one responsibility:

  • Connection Handling (Dial and HangUp)
  • Data Transfer (Receive and Send)

To avoid this tight coupling 3 different class must be created that may then be used together in aggregation or composition.

Fig2_SRP_After

Thus each class class has now only one responsibility:

  • Connection : Connection Handling (Dial and HangUp)
  • Data Channel : Data Transfer (Receive and Send)
  • Modem : Regroups the necessary functionality

Modifications to Connection Handling and Data Transfer can now be done independently in each corresponding class without any impact.


Share/Save/Bookmark

Tuesday, November 2, 2010

[Publication] Article in French Programmez Magazine on Visual Studio 2010 and UML Modeling

You can find an article of 4 pages concerning Visual Studio 2010 and UML Modeling in the French Programmez magazine No.135 written by me, Guillaume Rouchon and Loic Baumann.

cover

First Page (low resolution)

Second and Third Page (low resolution)

Fourth Page (low resolution)

The article is written in French but as always I will write some English articles on my Blog in the next weeks. So stay tuned if you are interested in knowing how to use Visual Studio 2010 for UML Modeling.


Share/Save/Bookmark