2017-06-04 2 views
1

Dans le Red Book, Vernon modélise les entités BacklogItem et Sprint en tant qu'agrégats séparés. Je vois des avantages de cette approche, mais il y a un cas que je ne peux pas comprendre. Par exemple, j'ai besoin de mon agrégat Sprint pour appliquer la limite maximale d'éléments assignée. De plus, le BacklogItem doit être conscient du fait d'assigment pour s'assurer qu'il n'est pas assigné à plus d'un Sprint. L'affectation de BacklogItem à Sprint modifie donc deux agrégats dans une transaction, ce qui n'est pas ce que nous voulons faire. Je ne vois aucune bonne approche qui résout ce problème. L'expansion de l'agrégat implique de faire de BacklogItem une partie interne de Esprit. Ce qui n'a aucun sens à cause de la nessité de l'utiliser à l'intérieur d'autres agrégats (Release, Schedule). Une autre façon que j'ai trouvé est d'utiliser la cohérence éventuelle et juste alerter l'administrateur sur la double affectation du BacklogItem. Mais je le perçois comme invariant agrégé important et je voudrais gagner l'opportunité de l'imposer explicitement.Deux agrégats et une transaction - l'exemple du Red Book

Répondre

2

Une autre façon que j'ai imaginée est d'utiliser une cohérence éventuelle et de simplement alerter l'administrateur à propos de la double assignation du BacklogItem. Je pense que c'est la bonne réponse. J'ai besoin de mon agrégat Sprint pour appliquer la limite maximale d'éléments assignée.

Il y a une considération importante que vous pouvez ignorer: qui décide quels BacklogItems sont ajoutés à un Sprint? Est-ce une décision que le modèle prend pour lui-même, ou est-ce une décision prise par un être humain (ou une autre entité en dehors du modèle)? Parce que, dans la plupart des cas, le modèle ne devrait pas rejeter les décisions prises par les opérateurs humains; et il ne devrait pas forcer les opérateurs humains à changer de contexte pour sauter à travers les cerceaux du modèle.

Il est inutile d'exécuter cette commande si nous savons à l'avance que nous dépassons la limite des articles Sprint. Si le gestionnaire de commandes effectue cette vérification: $ sprint-> hasSpaceFor ($ item); cela ne serait-il pas considéré comme une fuite de connaissances?

Il y a plusieurs choses à considérer ici.

Les données qui ne font pas partie de l'agrégat sont les suivantes: ; un autre gestionnaire de commandes pourrait modifier ces données pendant que vous le vérifiez. Cela ne signifie pas que le vérifier est faux, mais cela signifie que le vérifier dans le gestionnaire de commandes n'est pas forcément mieux que de le vérifier ailleurs.

Deuxièmement, votre vérification de l'invariant dépend de l'ordre dans lequel les messages arrivent. L'opérateur humain peut avoir décidé de supprimer un élément d'un sprint pour faire de la place pour le nouveau - mais si l'ordre des messages est changé en transit (transport de messagerie non fiable), alors le modèle finit par rejeter ce qui devrait être une commande valide . Ce n'est pas bon.

Alternativement, les messages peuvent arriver dans l'ordre où ils ont été expédiés. L'opérateur humain sait que les deux opérations s'annulent et, par conséquent, peu importe l'ordre dans lequel il se produit, mais le modèle insiste pour que les décisions soient consignées dans un ordre spécifique. C'est le saut de cerceau - le modèle rend le travail plus difficile, au lieu de plus facile.

Et en outre, la valeur à l'entreprise d'obtenir le bon article dans le sprint peut être plus précieux que de déterminer lequel enlever. Aperçu clé: l'opérateur humain travaille avec les priorités de l'entreprise maintenant, mais le modèle en cours de production reflète les priorités au moment où il a été écrit - en d'autres termes, le modèle a capturé les priorités passées. Donc, vous voulez faire attention à ce que le modèle veto à l'opérateur. Plus précisément, vous voulez comprendre comment la valeur métier est dérivée en opposant son veto aux messages que vous recevez de l'opérateur humain, et décider où cette responsabilité doit être gérée - c'est peut-être une question d'interface utilisateur (en essayant de réduire le coût des erreurs de saisie de données?), plutôt que d'un problème de modèle de domaine.

+0

Voilà une bonne idée! Vous avez parfaitement raison :) Mais cela conduit à une autre considération. Pour les besoins de cette conversation, supposons que j'exécute ma commande sur la racine d'agrégat BackLogItem: – ayeo

+0

$ item-> assignToSprint ($ sprint); L'élément backlock vérifiera s'il n'est pas assigné à un autre sprint. Mais il devrait y avoir une autre vérification. Il n'y a aucun intérêt à exécuter cette commande si nous savons à l'avance que nous dépassons la limite des objets Sprint. Si le gestionnaire de commandes effectue cette vérification: $ sprint-> hasSpaceFor ($ item); ne serait-il pas considéré comme une fuite de connaissances? – ayeo

+0

Je suis d'accord avec tout ce que dit VoiceOfUnreason. Fondamentalement, votre agrégat de sprint pourrait juste avoir un paramètre qui indique si oui ou non il a un débordement. Cela pourrait être utilisé dans une interface utilisateur pour informer un utilisateur, mais ne devrait pas être ailleurs. Pour fermer un sprint, vous pouvez rejeter s'il reste à ce moment des éléments encore ouverts. Bien sûr, il est possible qu'un article se ferme encore, mais il est raisonnable d'exiger que tous les articles soient fermés. Par contre, si vous déplacez un Backlog qui est déjà dans un sprint, votre commande peut être 'MoveBacklog' et nécessite un Sprint source et cible. – Arwin