vendredi 12 juillet 2013

Une femme à découvrir, Barbara Liskov (SOLID 3/5)

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

Nous arrivons au numéro 3 des 5 principes SOLID, le bien nommé principe de substitution de Liskov !

Barbara Liskov est une informaticienne ! Oui ça existe. Son principe est le suivant :

Si q(x) est une propriété démontrable pour tout objet x de type T, alors q(y) est vraie pour tout objet y de type S tel que S est un sous-type de T.

A copier 100 fois. Donc vous aurez compris que c'est le plus violent des cinq principes. Mais c'est pas si compliqué. En résumé, ça dit que si ça marche pour MaClass, ça marche aussi pour MaClassDerivé.

Si ça ressemble à un canard, caquette comme un canard, mais a besoin de piles, tu as probablement la mauvaise abstraction

Ça ne s'applique déjà que dans le cas ou 2 classes existent, et l'une hérite de l'autre.

Imaginons une classe Canard, et créons une sous classe CanardEnPlastique.
Si on décide que Canard peut voler, alors le code suivant est valide :

Canard couin = new Canard();
couin.EnvoleToi();

Par contre le programme suivant lance une Exception CanardEnPlastiqueNeVolePasException :

Canard couin = new CanardEnPlastique();
couin.EnvoleToi();

On ne peut pas substituer un canard en plastique à un vrai canard, c'est trop différent. On ne respecte pas le principe de substitution de Liskov. Pourtant tu l'as déjà fait dans ton code, on l'a tous fait. Et c'est mal. La prochaine fois que tu hérites d'une classe, penses à couin couin. Ne lance pas d'exception quand tu surcharges un comportement. Tout ce que fait la super classe, ta sous classe doit être au pire capable d'autant, c'est le minimum. L'héritage n'est pas fait pour limiter les capacités des classes mères, mais au contraire d'augmenter leurs capacités.

On peut voir ça comme des contraintes. Ce qui rentre dans la sous classe doit être au pire moins contraignant que ce qui peut rentrer dans la super classe. La sous classe doit être moins chiante. Si tu peux rentrer des pommes dans la super classe, la sous classe pourra elle prendre tout les fruits.

Inversement, tout ce qui sort doit être plus contraignant. Si la super classe sort des Girafes, la sous classe pourra sortir des bébés girafes par exemple. Par contre elle pourra pas sortir des éléphants. Si vous aimez le formalisme, l'explication de Wikipédia est beaucoup moins drôle:
  • Les préconditions ne peuvent pas être renforcées dans une sous-classe. Cela signifie que vous ne pouvez pas avoir une sous-classe avec des préconditions plus fortes que celles de sa superclasse.
  • Les postconditions ne peuvent pas être affaiblies dans une sous-classe. Cela signifie que vous ne pouvez pas avoir une sous-classe avec des postconditions plus faibles que celles de sa superclasse.
Gardons en tête qu'une sous-classe doit ajouter des fonctionnalités à la super-classe, et en aucun cas en limiter le comportement.

Sous-classer le canard en lui ajoutant la caractéristique plastique, c'est lui enlever la possibilité de voler. C'est pas SOLID !