Dernièrement, j'ai commencé à penser qu'avoir beaucoup de classes de manager dans votre conception était une mauvaise chose. L'idée n'a pas suffisamment mûri pour que je puisse présenter un argument convaincant, mais voici quelques points généraux:
J'ai trouvé qu'il était beaucoup plus difficile pour moi de comprendre les systèmes qui dépendent fortement des "gestionnaires". En effet, en plus des composants réels du programme, vous devez également comprendre comment et pourquoi le gestionnaire est utilisé.
Les gestionnaires, la plupart du temps, semblent être utilisés pour atténuer un problème de conception, comme lorsque le programmeur ne pouvait pas trouver un moyen de faire fonctionner le programmeTM et a dû compter sur les classes de gestionnaire pour que tout fonctionne correctement.
Bien sûr, les gérants peuvent être bons. Un exemple évident est un EventManager
, une de mes constructions préférées de tous les temps. : P Mon point est que les gestionnaires semblent être surutilisés la plupart du temps, et pour aucune autre bonne raison que de masquer un problème avec l'architecture du programme.
Les classes de manager sont-elles vraiment un signe de mauvaise architecture?
Les classes de gestionnaire peuvent être le signe d'une mauvaise architecture, pour plusieurs raisons:
Identifiants sans signification
Le nom FooManager
ne dit rien sur ce que fait réellement la classe , sauf qu'il implique en quelque sorte des instances de Foo
. Donner à la classe un nom plus significatif élucide son véritable objectif, ce qui conduira probablement à une refactorisation.
Responsabilités fractionnaires
Selon le principe de la responsabilité unique, chaque unité de code doit servir exactement un objectif. Avec un manager, vous divisez peut-être artificiellement cette responsabilité.
Prenons un ResourceManager
qui coordonne la durée de vie des instances de Resource
et y accède. Une application possède une seule ResourceManager
à travers laquelle elle acquiert des instances de Resource
. Dans ce cas, il n'y a aucune raison réelle pour laquelle la fonction d'une instance ResourceManager
ne peut pas être servie par des méthodes statiques dans la classe Resource
.
Abstraction non structurée
Souvent, un gestionnaire est introduit pour éliminer les problèmes sous-jacents avec les objets qu'il gère. C'est pourquoi les managers se prêtent aux abus comme pansements pour des systèmes mal conçus. L'abstraction est un bon moyen de simplifier un système complexe, mais le nom "manager" ne donne aucune idée de la structure de l'abstraction qu'il représente. Est-ce vraiment une usine, un proxy ou autre chose?
Bien sûr, les managers peuvent être utilisés pour plus que du mal, pour les mêmes raisons. Un EventManager
- qui est en réalité un Dispatcher
- met les événements en file d'attente à partir des sources et les envoie aux cibles intéressées. Dans ce cas, il est logique de séparer la responsabilité de recevoir et d'envoyer des événements, car un individu Event
n'est qu'un message sans notion de provenance ou de destination.
Nous écrivons un Dispatcher
d'instances de Event
pour essentiellement la même raison que nous écrivons un GarbageCollector
ou un Factory
:
n gestionnaire sait ce que sa charge utile ne devrait pas avoir besoin de savoir.
C'est, je pense, la meilleure justification pour créer une classe de type manager. Lorsque vous avez un objet "charge utile" qui se comporte comme une valeur, il doit être aussi stupide que possible pour que le système global reste flexible. Pour donner un sens à des instances individuelles, vous créez un gestionnaire qui coordonne ces instances de manière significative. Dans toute autre situation, les gestionnaires ne sont pas nécessaires.
Les managers peuvent être le signe d'une mauvaise architecture, mais le plus souvent ils ne sont que le signe d'une incapacité de la part du designer à trouver de meilleurs noms pour ses objets, ou simplement une réflexion du fait que la langue anglaise (et toute langue humaine d'ailleurs) est adaptée pour communiquer des concepts pratiques de tous les jours, et non des concepts très abstraits, très techniques.
Un exemple simple pour illustrer mon propos: avant que le Factory Pattern ne soit nommé, les gens l'utilisaient, mais ils ne savaient pas comment l'appeler. Ainsi, quelqu'un qui a dû écrire une fabrique pour sa classe Foo
l'a peut-être appelée FooAllocationManager
. Ce n'est pas un mauvais design, c'est juste un manque d'imagination.
Et puis quelqu'un doit implémenter une classe qui gère de nombreuses usines et les distribue à divers objets qui les demandent; et il appelle sa classe FactoryManager
parce que le mot Industry
ne lui vient tout simplement pas à l'esprit, ou il pensait que ce ne serait pas cool car il n'avait jamais entendu parler de quelque chose comme ça dans la programmation. Encore une fois, un cas de manque d'imagination.
Avoir beaucoup de classes "manager" est souvent le symptôme d'un modèle de domaine anémique , où la logique du domaine est hissée hors du modèle de domaine et placée à la place dans des classes manager, qui correspondent plus ou moins à - scripts de transaction . Le danger ici est que vous revenez essentiellement à la programmation procédurale - qui en soi peut ou non être une bonne chose en fonction de votre projet - mais le fait qu'elle n'a pas été envisagée ou prévue est le vrai problème imo.
Suivant le principe du "expert en information" , une opération logique devrait résider le plus près possible des données dont elle a besoin. Cela signifierait replacer la logique du domaine dans le modèle de domaine, de sorte que ce sont ces opérations logiques qui ont un effet observable sur l'état du modèle de domaine, plutôt que des `` gestionnaires '' changeant l'état du modèle de domaine de l'extérieur.
Réponse courte: cela dépend .
Il existe plusieurs formes distinctes de "classes de gestionnaire", certaines sont bonnes, d'autres mauvaises, et pour la plupart d'entre elles, cela dépend beaucoup du contexte si l'introduction d'une classe de gestionnaire est la bonne chose. Un bon point de départ pour bien les faire est de suivre le principe de responsabilité unique - si vous savez exactement de quoi chaque classe de manager est responsable (et ce qui ne l'est pas), vous aurez beaucoup moins de problèmes à les comprendre .
Ou pour répondre directement à votre question: ce n'est pas le nombre de classes de managers indiquant une mauvaise architecture, mais en avoir trop avec des responsabilités floues, ou traiter trop de soucis.
Bien qu'il puisse être facile de dire qu'ils sont intrinsèquement révélateurs d'une mauvaise conception, ils peuvent servir à apporter beaucoup de bien et à réduire la complexité du code et d'autres codes standard tout au long du projet en englobant une tâche et une responsabilité uniques universellement.
Bien que la prévalence des gestionnaires puisse être due à un mauvais jugement sur la conception, il peut également s'agir de gérer les mauvaises décisions de conception ou les problèmes d'incompatibilité avec d'autres composants dans une conception à composants ou des composants d'interface utilisateur tiers, ou des services Web tiers avec une interface étrange comme exemples.
Ces exemples montrent où ils sont terriblement utiles dans certaines situations pour réduire la complexité globale et promouvoir un couplage lâche entre divers composants et couches en encapsulant le "code laid" en un seul endroit. Un truc cependant serait que les gens trouvent tentant de faire des managers en singletons, je déconseille cela, et bien sûr, comme d'autres l'ont suggéré, le principe de responsabilité unique devrait toujours être suivi.
Les classes de manager peuvent-elles être le signe d'une mauvaise architecture?
Vous avez répondu à votre question: ils ne doivent pas nécessairement être le signe d'un mauvais design.
À l'exception de l'exemple de votre question avec EventManager, il y a un autre exemple: dans le modèle de conception MVC , le présentateur peut être considéré comme un gestionnaire du modèle/voir les classes.
Cependant, si vous abusez d'un concept, c'est le signe d'une mauvaise conception et éventuellement d'une architecture.
Lorsque la classe a "Manager" dans le nom, méfiez-vous du problème godclass (un avec trop de responsabilités). S'il est difficile de décrire ce dont une classe est responsable avec son nom, c'est un panneau d'avertissement de conception.
Mis à part les mauvaises classes de gestion, le pire nom que j'ai jamais vu était "DataContainerAdapter"
"Données" devrait être une autre de ces sous-chaînes interdites dans les noms - ce sont toutes des données, "données" ne vous en disent pas beaucoup dans la plupart des domaines.
Les classes de gestionnaire - tout comme presque toute classe se terminant par "-er" - sont mauvaises et n'ont rien à voir avec la POO. C'est donc pour moi un signe de mauvaise architecture.
Pourquoi? Le nom "-er" implique qu'un concepteur de code a pris des mesures et l'a converti en classe. En conséquence, nous avons une entité artificielle qui ne reflète aucun concept tangible, mais une action. Cela semble très procédural.
En plus de cela, ces classes prennent généralement des données et les exploitent. C'est une philosophie de données passives et procédures actives et elle a trouvé sa place dans la programmation procédurale. Si vous vous rendez compte, il n'y a rien de mal dans les classes Manager, mais ce n'est pas OOP alors.
La pensée d'objet implique que les objets se font des choses à eux-mêmes. Découvrez votre domaine , construisez réseaux sémantiques , laissez vos objets être des organismes vivants, des humains intelligents et responsables.
De tels objets n'ont pas besoin d'être contrôlés. Ils savent quoi faire et comment faire. Donc, les classes Manager cassent deux fois les principes OOP. En plus d'être une classe "-er", elle contrôle d'autres objets. Mais cela dépend du gestionnaire. Mais il contrôle - c'est un mauvais gestionnaire. Si il coordonne - c'est un bon manager. C'est pourquoi une lettre "C" en MVC doit être orthographiée comme "Coordinateur".
La bonne réponse à cette question est:
Chaque situation que vous rencontrerez lors de l'écriture du logiciel est différente. Peut-être êtes-vous dans une équipe où tout le monde sait comment fonctionnent les cours de manager en interne? Ce serait complètement fou de ne pas utiliser ce design. Ou si vous essayez de pousser la conception du gestionnaire à d'autres personnes, auquel cas ce pourrait être une mauvaise idée. Mais cela dépend des détails exacts.