dimanche 19 mai 2013

Le « S » de SOLID : Single Responsability Principe (SRP)


Le principe de responsabilité unique est un concept phare dans la programmation orientée objet. Il introduit le fait qu’une classe ne doit avoir qu’une seule responsabilité bien définie, afin qu’il n’existe qu’une seule raison pour qu’elle change.

Tous les jours, dans son travail, le développeur se confronte à des problèmes plus ou moins complexes. Résoudre les problèmes complexes dans leur globalité est très difficile, tant l’effort intellectuel est intense. La seule solution plausible est de découper le problème compliqué en problèmes plus simples à appréhender. Le principe SRP veut un découpage parfait, c’est-à-dire que chaque problème simple est résolu par une classe à responsabilité unique. 

Le code devient :
  • Plus facile à comprendre
  • Plus facile à modifier (corriger, étendre)
  • Plus facile à tester
  • Plus robuste

----------

Exemple :
Prenons par exemple une classe PersonProvider qui fournit des données de type Person. La méthode GetValidPersons() a pour but de retourner les personnes « valides » de la base de données.

public class PersonProvider
    {
        private readonly DatabaseAccess _databaseAccess;
        public PersonProvider()
        {
            _databaseAccess = new DatabaseAccess("localhost", 80, "Login", "Password");
        }
        public IEnumerable<Person> GetValidPersons()
        {
            return (from personne in _databaseAccess.Personnes
                    where personne.Sex == Person.SexType.F
                    where personne.Age > 18
                    select personne).ToList();
        }
    }

Comme vous vous en doutez, cette classe, bien que très simple, est à responsabilités multiples et ne respecte en aucun cas le principe SRP. Les fonctionnalités qu’elles assument sont :

  • Obtenir un contexte de données
  • Accéder à la source de données pour obtenir les personnes
  • Intégrer les conditions de sélection d’une personne « valide »


Si l’on souhaite faire évoluer l’une de ces trois fonctionnalités, nous devons forcément changer la classe PersonProvider.

Pour respecter le principe SRP, il faut modifier cette classe afin qu’elle soit à responsabilité unique. Par exemple :
public class PersonProvider
    {
        private readonly DatabaseAccess _databaseAccess;

        public PersonProvider(DatabaseAccess databaseAccess)
        {
            if (databaseAccess == null) {
                throw new ArgumentNullException("databaseAccess");
            }
            _databaseAccess = databaseAccess;
        }
        public IEnumerable<Person> GetValidPersons()
        {
            return (from personne in _databaseAccess.Personnes
                    where personne.IsValid
                    select personne).ToList();
        }
    }
public class Person
    {
        public enum SexType { M, F }

        public SexType Sex { get; set; }
        public string LastName { get; set; }
        public string FirstName { get; set; }
        public int Age { get; set; }

        public bool IsValid
        {
            get { return Sex == SexType.F && Age > 18; }
        }
    }

Les modifications apportées sont :
  • La classe obtient le contexte de données à utiliser dans son constructeur. Elle n’a donc plus la responsabilité de l’initialiser.
  • Le code indiquant si une personne est valide ou non, est déplacé dans la classe Person.
Ainsi, la classe PersonProvider, n’a plus que la responsabilité d’appliquer des critères de sélection de personnes sur une source de données définie. Le principe SRP est respecté.

----------

Ce principe, bien que simple à comprendre, est surement l'un des principes les plus durs à appliquer. Alors, amis développeurs, courage et persévérez ! Les avantages de SRP sont essentiels au sein d'un logiciel, peu importe sa taille.

Prochain poste d'architecture SOLID, on continue dans l'ordre : O pour Open/Closed Principle (OCP) !

Aucun commentaire:

Enregistrer un commentaire