domain driven design - DDD - Enforce invariants with small aggregate roots -
i'm having first attempt @ ddd , i'm running problem aggregate design.
my application contains 3 entities; graph, node, link. each of these entities has name property can modified user (which believe makes 'name' unsuitable entity id). graph contains collection of nodes , node has collection of outgoing links (for purpose of problem safe ignore incoming links). each node can associated 1 graph @ time (but can moved between graphs) , similarly, each link can associated 1 node @ given time (but can moved).
the invariant(s) attempting enforce entity names unique within parent collection. architecture described above, invariant on actual collections, decided collection owners (graph , node) should both aggregate roots.
the problem have how enforce name invariant on node? on link easy since hidden away inside node ar , such node can confirm link renames/moves not break invariant. far can see, there nothing prevent direct rename of node break invariant. eventual consistency not acceptable option here, must true system invariant.
the approach considering have node.rename() enforce invariant, concern involves looking inside parent graph check if rename valid. doesn't 'feel' right - feels graph should 1 enforce namespacing constraint , node should know nothing @ all.
i hope makes sense, , forward hearing peoples thoughts.
edit: domain model presented above simplified subset of entire domain. complex entities held within single ar.......
as concluded in comment, aggregate root should graph.
there difference between aggregates , aggregate roots. in example both graph , node aggregates, object responsible managing entire aggregate graph. root.
the easiest way idea if object aggregate root ask yourself:
does make sense have object, detached parent?
if answers no, it's not aggregate root. example, single node of little use when it's not part of parent graph. that's why have repositories aggregate roots; prevent having access objects not part of corresponding aggregate root.
now on invariants. stated (emphasis mine):
all [node] names unique within parent [graph]
you answered question right there. in context of single node doesn't make sense name unique. in context of graph does, because invariant of graph, not node. graph responsible protecting invariant.
as 'god aggregate root', it's not uncommon have single aggregate root global business perspective. important aspect of ddd identifying different contexts within system. system may have high-level root containing many graph objects. in high-level context of managing graphs, you're not interested in low-level link objects in graph.
it important model domain objects according context. 1 of important things i've come realize in last few months. people know ddd because of repositories, or maybe because of entities , value objects, these aren't important bounded contexts.
even though there 1 business concept of something, perfectly fine have multiple models represent concept of something, single implementation per context. 1 implementation might aggregate root, while other implementation part of larger aggregate, depending on context.
common software mantras code reuse, dry , likes, @ first felt wrong have multiple classes represent same business concept. once able let go of feeling , realize each implementation had own responsibilities, made things easier :)
Comments
Post a Comment