Où est la limite entre la délégation et l'encapsulation de la logique métier? Il me semble que plus nous déléguons, plus nous devenons anémiques . Cependant, la délégation encourage également la réutilisation et le principe de DRY. Alors, qu'est-ce qui convient de déléguer et que devrait rester dans nos modèles de domaine?
Prenons comme exemple les préoccupations suivantes:
Autorisation . L'objet de domaine doit-il être responsable de la gestion de ses règles de contrôle d'accès (comme une propriété CanEdit) ou doit-il être délégué à un autre composant / service uniquement responsable de la gestion de l'accès, par exemple IAuthorizationService.CanEdit (objet)? Ou devrait-il être une combinaison des deux? Peut-être que l'objet de domaine a une propriété CanEdit qui délègue à un IAuthorizationService interne pour effectuer le travail réel?
Validation . La même discussion que ci-dessus concerne la validation. Qui maintient les règles et qui est chargé de les évaluer? D'une part, l'état de l'objet doit appartenir à cet objet et la validité est un état, mais nous ne souhaitons pas réécrire le code utilisé pour évaluer les règles de chaque objet du domaine. Nous pourrions utiliser l'héritage dans ce cas ...
Création d'objet . Classe d'usine contre méthodes d'usine contre "nouveauté" d'une instance. Si nous utilisons une classe de fabrique séparée, nous pouvons isoler et encapsuler la logique de création, mais aux dépens de l'ouverture de l'état de notre objet à la fabrique. Cela peut être géré si notre couche de domaine se trouve dans un assemblage séparé en exposant un constructeur interne utilisé par l'usine, mais cela devient un problème s'il existe plusieurs modèles de création. Et si l’usine n’appelle que le bon constructeur, à quoi sert-elle d’avoir l’usine?
Les méthodes d'usine de la classe éliminent le problème d'ouverture de l'état interne de l'objet, mais comme elles sont statiques, nous ne pouvons pas rompre les dépendances en injectant une interface de fabrique comme avec une classe de fabrique distincte.
Persistance . On pourrait argumenter que si notre objet domaine doit exposer CanEdit tout en déléguant la responsabilité d'effectuer le contrôle des autorisations à une autre partie (IAuthorizationService), pourquoi ne pas avoir une méthode Save sur notre objet domaine qui répète les mêmes choses? Cela nous permettrait d'évaluer l'état interne de l'objet pour déterminer si l'opération peut être effectuée sans rompre l'encapsulation. Bien sûr, cela nécessite que nous injections l'instance de référentiel dans notre objet de domaine, ce qui sent un peu pour moi. Alors, levons-nous un événement de domaine à la place et permettons à un gestionnaire d'effectuer l'opération de persistance?
Vous voyez où je vais avec ça?
Rockford Lhotka a eu une discussion intéressante sur les raisons pour lesquelles il a choisi la voie de la classe responsable pour son framework CSLA. J'ai un peu d'histoire avec ce cadre et je peux voir son idée d'objets métier en parallèle avec des objets de domaine de plusieurs manières. Mais pour essayer de devenir plus adhérent aux bons idéaux DDD, je me demande quand la collaboration devient trop lourde.
Si je me retrouve avec IAuthorizationService, IValidator, IFactory et IRepository pour ma racine globale, que reste-t-il? Avoir une méthode Publish qui modifie l'état de l'objet de Brouillon à Publié est-il suffisant pour considérer la classe comme un objet de domaine non-anémique?
Tes pensées?