La loi de Demeter où le principe de la connaissance minimale
Vous avez certainement déjà fait : $this->getFirstObject()->getSecondObject()->doSomething() ? Vous avez déjà certainement eu des soucis a repasser à différents endroits de votre code quand l'interface du "SecondObject" change, voici un principe de développement logiciel qui alors nous être utile...
Le principe de Demeter dit qu'un objet a le droit d'accéder aux méthodes/opérations d'un autre objet, mais pas à celles d'un objet encapsulé dans un autre objet. Concrètement, nous avons le droit de faire :
$this
->getFirstObject()
->doSomething(...);
Mais nous n'avons pas le droit de faire :
$this
->getFirstObject()
->getSecondObject()
->doSomething();
Ce qui nous oblige donc dans le "first object" à fournir autant d'opérations que nécessaire pour éviter que la classe (représentée par $this dans notre cas) ne sache quel objet réalise réellement l'opération.
Par exemple, dans la ligne suivante :
$this
->getAdapter()
->getTypeDispositifService()
->contientDesPhases(
$this
->getAdapter()
->getIdTypeDispositifConcours($concours));
Le principe de Demeter n'est pas respecté car depuis le service (représenté par $this) nous n'avons pas le droit d'appeller une méthode sur le "TypeDispositifService", nous n'avons le droit d'appeller que des méthodes de l'adapter, nous devons donc créer une méthode dans l'adapter qui encapsule tout ca, par exemple :
$this
->getAdapter()
->contientDesPhases(
$this
->getAdapter()
->getIdTypeDispositifConcours($concours));
avec l'implémentation suivante :
class ...._Adapter_Default implements ..._Adapter_Interface
{
...
/**
* @return boolean
*/
public function contientDesPhases($typeDispositif)
{
return $this
->getTypeDispositifService()
->contientDesPhases($typeDispositif);
}
...
}
Une des conséquences positives de l'application de la loi de Demeter est l'augmentation des degrés d'adaptabilité, évolutivité, maintenabilité du code / de l'application. Une inconvénient est la nécessité d'encapsuler systématiquement les appels de second niveau, augmentant le nombre d'appel de méthodes à réaliser pour exécuter un code, ce point pouvant être relativement maîtrisé en mettant en oeuvre une architecture de type services la plus applatie possible (i.e. en évitant tant que possible les dépendances de dépendances de dépendances ... d'objets).
J'applique cette loi sur tout mes développements et je la conseille à mes développeurs, et personnellement nous avons un retour d'expériences positifs.
Pour une définition plus théorique et complète de la loi de Demeter, je vous propose de consulter Wikipédia.
Et vous, est-ce une règle que vous appliquez ? En appliquez vous d'autres contradictoires / complémentaires ?
Commentaires récents