Personnellement, je vois plus cette classe comme une God Class que comme une classe conteneur. Cette classe est tellement chargée qu'elle est utilisée partout dans le code, je suppose - avec la conséquence que si le code a besoin d'avoir accès à
un manager, il va devoir se résoudre à dépendre des autres quand même.
Le problème de ce design n'est pas encore lié à l'utilisation de la loi de Demeter, mais bien à l'architecture elle-même. Le premier problème, c'est la notion de manager. Si on essaye de répondre à la question "que fait un manager de X", la réponse est invariablement "il gère des X". Gérer ne voulant rien dire (pas de définition précise ; ou plus exactement, tellement de définition qu'on se retrouve avec un petit problème de sémantique...). A la base, un manager est nécessairement une god class, du fait même de son nom. On s'en sert donc partout. Puisqu'on s'en sert partout, la tentation est grande de grouper les managers dans une classe, ce qui transforme celle-ci en hyper-god class, qui est utilisée encore plus partout. A terme : le code devient impossible à maintenir car le moindre changement dans un manager risque d'avoir un impact sur l'ensemble du code.
Si tu veux voir à quel point World est une god class, commence par encapsuler tous les appels à chacune des fonctions du manager par des méthodes dans World (c'est la base de la loi de Demeter, après tout). TU va rapidement t'apercevoir que le nombre de méthodes explose littéralement.
Je n'aime pas les manager. Ils sont trop étendus en termes de responsabilités (on en revient toujours à ça dans cette discussion
), sans pour autant définir quel est leur rôle exact. On finit par en avoir tellement marre de leur omniprésence qu'on les transforme en singletons, parce que bon, hein, il ne peut en rester qu'un... Ce n'est pas toujours le cas (parce que des fois, on peut trouver sympathique d'avoir plusieurs managers du même type) mais dans la pratique, ça se termine souvent comme ça quand même.
Dès lors qu'on commence à se dire "et là, je vais mettre un manager de X", il faut se poser la question de pourquoi. A quoi va servir ce manager ? Quelles seront ses fonctions ? N'y a-t-il pas un découpage plus sensé, qui permettrait très certainement un plus grand découplage ?
Si on reprends un exemple classique - une "manager de ressources" dans un programme basé sur DirectX, ce manager est une combinaison d'au moins trois fonctions différentes : une fonction de factory, une fonction de collection, et une fonction de contrôle de la durée de vie. Bon nombre d'algorithmes n'ont pas besoin de connaitre la factory et la fonction de contrôle de la durée de vie (par exemple, la récupération sur une erreur device lost). S'il est évident (et encore) que la factory et le contrôle de la durée de vie peuvent s'appuyer sur la collection (l'un pour ajouter des éléments, l'autre pour les supprimer), il n'en reste pas moins que les fonctions ne sont pas liées entre-elles. La fonction de contrôle de la durée de vie est totalement indépendante de la fonction factory, et inversement.
Bon nombre de managers sont en réalité mieux représentés par plusieurs classes. En ajustant au mieux le découpage d'un manager, on affine aussi son utilisation, qui est nécessairement moins globale que l'utilisation du manager complet. Ce qui permet de réduire le couplage entre les classes. Ce qui permet de ne pas avoir à créer de god class. Ce qui permet de rendre la loi de Demeter plus efficace.
Partager