Archives par étiquette : interfaces

Les principes SOLID expliquées à ma fille

Ma fille ne comprend rien à l’informatique. Il faut dire qu’à 6 ans, on a autre chose à faire que de se passionner pour ces choses bizarres ! Et puis l’informatique ça a l’air compliqué ! On voit souvent Papa se prendre la tête à deux mains en se demandant pourquoi c’est fait de manière si compliquée alors que le problème adressé est on ne peut plus simple. J’ai tout de même essayé de m’imaginer en train d’expliquer à ma petite tête brune à couettes les principes SOLID, énoncés par « Uncle Bob » il y a maintenant plus d’une décennie.

Commençons par le commencement : le S de SOLID, c’est pour Single Responsibility (responsabilité unique) : une classe n’est pas comme ces équipiers qu’on voit au comptoir des fast-foods; elle ne doit pas faire le drive-in, servir les boissons, nettoyer les tables, faire chauffer les frites, non : UNE SEULE chose à la fois.

Le O c’est pour Open/Closed (ouvert/fermé) : une classe doit être fermée à la modification (de son code source) mais ouverte à l’extension : on n’essaie pas de faire rentrer un carré dans un rond, on crée une « forme », qu’on spécialisera ensuite en rond, carré, losange, triangle, etc.

Le L rend hommage à Madame Barbara Liskov et son principe de substitution: mon objet chimpanzé de la classe Singe a une méthode manger(Fruit) : la banane, la mangue et la noix de coco sont des fruits; ma méthode manger doit avoir le même comportement que je fasse manger(Banane), manger(Mangue) ou manger(Coco), c’est à dire si je substitue le sous-type Banane, Mangue ou Coco au super-type Fruit.

Le I évoque la ségrégation des interfaces (Interface Segregation) : certains animaux savent voler, le singe est un animal mais ne sait pas voler. Pourquoi le faire dépendre d’une classe Animal qui implémenterait une interface AnimalVolant si on sait qu’il ne volera jamais ? Ce principe est très simple : une classe ne doit pas dépendre d’interfaces dont elle n’a pas l’utilité ! L’objectif est ici, une fois de plus, de réduire le couplage inutile entre les classes.

Le dernier de ces 5 principes est le principe d’inversion des dépendances (D pour Dependency Inversion). A est client de B, lui-même client de C; on peut dire que A dépend de B qui dépend de C. Prenons A et B: ce n’est plus A qui va dépendre de B, mais A qui va dire à B ce dont il a besoin. B ne dit plus à A « voilà comment je fonctionne, débrouille toi ! », c’est A qui dit à B « voilà ce dont j’ai besoin, donne le moi ! »…Nous avons donc bien inversé le rapport de force entre fournisseur et client !

Allez, je vous laisse, j’ai un match entre les Littlest Pet Shop et les My little Pony à gérer…

IMG_3521

Sources :

Pour ceux que l’anglais ne rebute pas, je vous conseille l’excellent site d’Oncle Bob et ses hilarants (autant qu’instructifs) codecastsCleanCoders

Toujours dans la langue de Shakespeare…

http://aspiringcraftsman.com/2008/12/28/examining-dependency-inversion/

PHP : héritage multiple des interfaces

Vous le savez sûrement, les interfaces servent à contraindre des classes à implémenter une ou des méthodes publiques. N’importe quelle classe, abstraite ou concrète, peut les implémenter. Mais saviez-vous que, contrairement aux classes, les interfaces peuvent hériter de plusieurs parents ?

Prenons l’exemple suivant ;


interface Counterializable extends Serializable, Countable {
    public function counterialiser();
}

class CompteEtSerialise implements Counterializable {}

Ici, l’interface Counterializable (contraction de Countable et de Serializable) impose à notre classe concrète CompteEtSerialise l’implémentation de 4 méthodes:
– deux provenant de Serializable (serialize et unserialize)
– une provenant de Countable (count)
– une provenant de Counterializable (counterialiser)

Si l’on exécute ce code, il se produit l’erreur suivante :

PHP Fatal error: Class CompteEtSerialise contains 4 abstract methods
and must therefore be declared abstract or implement the remaining
methods (Counterializable::counterialiser, Serializable::serialize,
Serializable::unserialize, ...)

Ce message d’erreur est bien la preuve que l’héritage multiple, qui ne s’applique pas aux classes, s’applique en revanche aux interfaces !