lundi 15 juillet 2013

Ségrégation des interfaces (SOLID 4/5)

Ce post fait partie de la série S.O.L.I.D.

L'avant dernier principe SOLID est la ségrégation des interfaces. Si le terme séparation est connu, le terme ségrégation l'est un peu moins.

Wiktionnaire nous dit :
Action par laquelle on met quelqu’un ou quelque chose à part, on le sépare d’un tout, d’une masse.
C'est très précis, il faut mettre à part les interfaces.

Tu veux que je branche ça. Où ?
L'idée est que le client qui va utiliser vos interfaces ne se retrouvent pas avec des interfaces à 150 méthodes, parce que la classe sous-jacente contient 150 méthodes. Chaque interface doit avoir un but unique, et l'on retrouve le premier principe de responsabilité unique.

Prenons une pizzeria. Une pizzeria fait des pizzas, les livre, encaisse votre argent, paye ses impôts, paye ses employés, subit un contrôle sanitaire de temps en temps.

Imaginons que vous voulez commander une pizza à une pizzeria qui hérite de l'interface IPizzeria.

Supposons l'interface suivante :

interface IPizzeria
{
    Pizza Order(PizzaType type);
    void Deliver(Pizza pizza, Location address);
    void Pay(decimal dollar);
    void PayTaxes(decimal dollar);
    void PayEmployees(List<Employee> employees);
    void HealthControl();
}


Vous, client, vous souhaitez appeler la pizzeria pour commander la pizza choisi par l'utilisateur :

public Pizza OrderPizza(IPizzeria pizzeria)
{
    PizzaType type = (PizzaType)comboBoxPizzaType.SelectedItem;
    return pizzeria.Order(type);
}

Là tout se passe bien. Mais comme l'interface n'a pas été ségrégationnée, un risque aurait été d'appeler le contrôle sanitaire.

public Pizza OrderPizza(IPizzeria pizzeria)
{
    PizzaType type = (PizzaType)comboBoxPizzaType.SelectedItem;
    pizzeria.HealthControl();
}

Vous imaginez le bazar si à chaque commande client les inspecteurs se pointent ?
Outre le faite de se tromper de méthode, le principe de ségrégation permet un découpage net et précis du code. Certes, votre objet fait plein de choses. Ce n'est pas la peine que le monde entier soit au courant.

Vous client, vous ne devez voir que ce qui vous intéresse de la pizzeria :

interface IOrderablePizza
{
    Pizza Order(PizzaType type);
    void Deliver(Pizza pizza, Location address);
    void Pay(decimal dollar);
}

D'un autre côté, les inspecteurs sanitaires se foutent royalement que vous livrez des pizzas. Ce qui les intéresse, c'est la caractéristique entreprise de la pizzeria :

interface IBusiness
{
    void PayTaxes(decimal dollar);
    void PayEmployees(List<Employee> employees);
    void HealthControl();
}

Notre pizzeria finit par hériter de ces deux caractéristiques : c'est une entreprise (paye des impôts, des employés, subit des contrôles), qui fait des pizzas (cuisine, livraison).

class DaEnzoPizza : IOrderablePizza, IBusiness
{
}