Memo: Design Principles in Object Oriented Programming

What are Design Principles?

Design principles are guidelines to produce software’s that are easier to test, to maintain and to extend.

SOLID

SOLID is a mnemonic acronym that stands for:

Single Responsibility Principle

Says that a component should only focus on a single responsibility, the one for which the module exists. A module can be different things like a use case, a package, a module or a class. Of course, the lower you go through layers the more your classes will focus on specific things.

Examples

  1. “Model-View-Controller” is example of this principle. The design pattern promote the separation of concern through multiple layer – each one responsible on a specific concern.
  2. Another simple example of this principle is to never instantiate new objects inside your classes. Because each time you use new and you create a static dependency you add to you class the responsibility to make its dependencies.

Open/Closed Principle

Says that a component should be closed for modifications but open for extensions. This means that if you have to change the internal working of a class you should be able to create a new one that inherit from the one you want to modify and apply your changes on it. You should never change the code and the internal working of your existing components.

If you apply SOLID principle you will be able to replace the old implementation by the new without any impact on the solution.

Example

Diagramme de classe 2

Here is the class diagram for a simple application that reads a file in specific format and writes what it reads into another. Actually the application read XML files and produce a JSON file. If you want to customize the internal working of the “XmlReader” you should absolutely avoid to change its code. You should be able to create a new class (“XmlReaderNg”) that inherit from “XmlReader”, change the internal working and after tell to the “FileTransformer” to use your new class instead of the old one.

In conclusion: Always extend, never change.

Liskov Substitution Principle

Says that a base class has to be able to be replaced by a child class without any impact on the solution.

Example

If you take a look at the Open/Closed Principle example and you replace the “XmlReader” by the new implementation “XmlReaderNg” the replacement shouldn’t have any impact on the way of “FileTransformer” works.

Interface Segregation Principle

Promote the use of multiple simple interface instead of a big and complex one.

Examples:

In C#: IDisposable, ISerializable.

Dependency Inversion Principle

Says that:
–       high level modules should never depends on low level modules. Both should depends on abstractions;
–       Abstractions should not depend upon details. Details should depend upon abstractions.

I have already wrote an article on it: https://erichonorez.wordpress.com/2012/11/24/dependency-inversion/

Inversion Of Control

The Inversion of Control is design principle that aids to create loosely couple applications. In fact this design principle will act as a glue for SOLID principles.

The aim of the Inversion Of Control is to provide dependencies of a component at runtime instead of compile time. For that purpose a “dependency provider” is used. There are two different implementations of this principle and the main difference between the two is the way you use them.

Service Locator

The component is responsible to retrieve its dependencies form the service locator.

Example

Here is a very simple implementation of Repository class that retrieve tasks from the persistence layer.

public class TasksRepository : ITaskRepository
{
    private ILogger _Logger;
    public TasksRepository(IServiceLocator serviceLocator)
    {
        serviceLocator.GetService<ILogger>();
    }
}

This class use an ILogger object to log what it does and retrieve an instance of ILogger by requesting it to the IServiceLocator.

Cons: By using the ServiceLocator implementation of IoC you create a dependency between the components that the container and its API.

Dependency Injection

The dependency injection container provide (inject) dependencies to the component. This injection can be done by different ways:
–       Constructor parameters
–       Setting some properties
–       Calling methods

Example

By using a Dependency Injection Container your TaskRepository will look like more like that:

public class TaskRepository : ITaskRepository
{
    private ILogger _logger;
    public TaskRepository(ILogger logger)
    {
        this._logger = logger;
    }
}

The caller will request to the container to provide him an instance of ITaskRepository. The ILogger will be injected directly.

Resources

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s