Network
由与Node
s连接的Fiber
组成。 Network
负责确保:
Node
; Node
; Network
,Node
和Fiber
都是信息丰富的(他们有名字,部署时的日期等),它看起来像我如果Network
是聚合根(因为它是Node
和Fibers
的容器,并强制它们之间存在不变量。)
我此时还确定Node
和Fiber
是实体,而且它们也可能是聚合根。
Network
类的一种可能实现可能如下:
class Network {
private final NetworkId id;
private String name;
private Location location;
...
private final Map<FiberId, Fiber> fibers = new HashMap<FiberId, Fiber>();
private final Map<NodeId, Fiber> nodes = new HashMap<NodeId, Node>();
}
如果我的用例只是编辑Network
的位置或名称,那么会带来很大的问题。在那种情况下,我只是不关心光纤和节点,实际上,预计它们的数量很可能达到10k-100k节点/光纤的数量级!
我该如何处理这个问题?我应该将Network
(包含fibers
和nodes
及其不变量)的定义与其他字段分开吗?
我一直认为聚合根作为具有一组不变量来保持其属性的实体,与不关心其属性状态的实体形成鲜明对比(例如,使用姓名和年龄定义的人可能不需要检查名称和年龄的无效组合。
遵循这一理念,我通常倾向于决定一些域概念是价值,实体,价值还是事件,然后如果它是一个实体,如果它是一个聚合根。我的假设有缺陷吗?
由于
答案 0 :(得分:3)
首先,不要浪费时间思考哪个是实体或价值对象。这样的技术细节由它们自己出现。重要的是模拟正确概念。那么,网络对网络的理解是什么?它是Nodes或Fibes的容器还是其本身的逻辑单元?
你有没有任何Node或Fibe的网络吗?域中是否存在空网络?网络是否包含节点和Fibe,或节点和Fibe是否在网络中组织(按分组)?您必须确定Node或Fibe的集合是否真的 define 一个网络,即您没有这些概念就无法拥有有效的网络概念。
同样确实重要有界上下文,网络概念特定于一个上下文,在其他上下文中可能看起来有点不同。到处都没有一个单一的模型有效。那么,您在什么情况下定义网络?您只需要定义与该上下文相关的内容,而不是在某些时候定义可能属于网络的所有内容。
不要将DDD作为配方,寻找识别聚合根(AR)的技术模式。有机地做,只是尝试根据特定的域上下文设计模型。你知道什么时候AR不仅仅是一个实体。
作为一个拇指规则,AR is not a container它仍然是一个域概念,它恰好充当其他相关概念的外观。
答案 1 :(得分:1)
如何将不变保护委托给较小的聚合根?
1.任何光纤的两端都连接到节点;
2.没有两端连接到同一节点;
我认为这两者可以受到Fiber的保护。虽然下面这个有点棘手,但一个简单的解决方案是在位置上使用数据库约束。
3.没有两个节点可以在同一个(x,y)位置。
然后,网络只是一个具有身份和一些信息的聚合根。