J'essaie d'appliquer l'architecture propre d'oncle Bob à une application que je gère et j'ai des difficultés avec les cas d'utilisation et la duplication/réutilisation. Je crois comprendre que les cas d'utilisation devraient être autonomes et qu'il faut s'attendre à des doubles emplois, mais cela ne semble pas avoir de sens avec ce que je traite. Je pense qu'il existe plusieurs cas d'utilisation qui devraient finir par utiliser d'autres cas d'utilisation.
Voici un exemple très simplifié de 4 cas d'utilisation qui existent séparément mais qui dépendent également les uns des autres de la manière suivante.
BulkSendUsersToUnit
SendUserToUnit
AddUserToMandatoryGroups
AddUserToGroup
Chacun d'eux a une validation, des appels de référentiel et des conditions qui s'appliquent toujours. Fondamentalement, si je faisais cela avec des services, ce seraient simplement des méthodes que j'appellerais d'où j'en aurais besoin.
Puis-je/dois-je injecter des cas d'utilisation dans d'autres cas d'utilisation en utilisant DI?
Qu'est-ce que j'oublie ici?
Un cas d'utilisation n'est pas une méthode.
Un cas d'utilisation n'est pas un objet.
Un cas d'utilisation n'est pas un calque.
Un cas d'utilisation est une histoire d'un utilisateur, utilisant le logiciel, dans un cas particulier.
Il n'est donc pas surprenant que différents cas d'utilisation puissent réutiliser le même code.
Mais peut-être que vous avez regardé l'une des vidéospaywalled où Bob fait comme un cas d'utilisation fait partie de votre architecture.
Ne t'inquiète pas. C'est juste un nom pour les boîtes dans l'une de ses couches. Il a utilisé d'autres noms pour cela :
Est-ce à dire que l'oncle Bob a tort? Non. La couche Interactor/Use Case/Application Business Rule/Oh-pick-a-name-and-stick-with-it est l'endroit où vous ignorez tous les besoins de votre application (détails) et vous concentrez sur les besoins de l'utilisateur. en passant par un cas d'utilisation particulier. Mais cet emplacement dans votre code n'est pas LE cas d'utilisation. Le cas d'utilisation est toute l'histoire depuis le moment où l'utilisateur clique sur un bouton jusqu'au moment où il voit le résultat.
Les interacteurs (ou quel que soit leur nom) devraient-ils donc utiliser d'autres interacteurs? Eh bien, c'est le hic de suivre DRY à l'extrême. Vous n'êtes pas autorisé à mettre le code de AddUserToGroup
nulle part ailleurs non?
Balivernes. Si AddUserToMandatoryGroups
signifie quelque chose de différent, a une raison différente de vouloir changer que AddUserToGroup
, alors il est correct de donner à AddUserToMandatoryGroups
son propre code d'utilisateur supplémentaire. Même si en ce moment c'est un caractère pour la copie de caractères du code dans AddUserToGroup
. Si vous avez de bonnes raisons de penser que celles-ci doivent pouvoir changer indépendamment les unes des autres, cela n'a pas d'importance si, à l'heure actuelle, elles semblent identiques. Appliquer DRY aux idées répétitives. Pas de code.
En ce qui concerne l'injection de dépendances, cela fonctionne toujours bien quand vous voulez découpler quoi et quand.
Bulk shitlist = new Bulk(annoyingUsers, bannedForLifeUnit);
Register.OnIveHadAllICanTake( ()-> shitlist.send() );