我有一个有界上下文,其中两个聚合是该特定模型中业务的核心。模型开始表现得很好,但是
需要
是双向的(我正在探索和做其他的设计,所以可能我最终找到了更好的方法)。
让我们说
A
和
B
是每个聚合的聚合根。
一
和
乙
有一个
n:m
联系。周围的不变量
一
至少需要跟踪
乙
,并且在
一
(许多用户修改
一
同时,很可能
一
)生意上说这里不变
必须
强制执行(不允许最终一致性)。如果用户试图“附加”的实例
乙
以…为例
一
(当然,这在ul中有一个概念),规则要求检查
乙
,包括其他
一
与之相关。这是至关重要的,因为操作可以根据分析而被拒绝,因此保留了集合的不变量。上存在低并发争用
乙
(不同的用户不太可能尝试修改相同的
乙
,可能是用户的错误)。
因为在
乙
,在同一事务中保存两个聚合不会造成什么损害。但是“附加”操作
一
只需要
现在的
状态
乙
,因此可以在当前事务中保持它们不同步,但下一个事务(可以立即启动)需要查看上一个事务的更改。
我通过阅读蓝皮书和红皮书知道,在某些情况下,存储库可以返回一个值对象,而不是整个聚合,但是
让储存库水合部分的状态
乙
源于
一
在数据库级别?
当前事务可能发生变化并保存
一
无需修改
乙
. 然后下一个事务检索
乙
再一次,但是这次的变化是可见的,因为
乙
重新生成以检查
一
在仓库里。
我的问题不是实现本身,而是模型:通过这种方法,模型表达了
一
与许多
乙
S和
一
具有修改该集合的正确操作(“附加”操作)。但即使
乙
与许多
一
s,需要从
乙
对其
一
因此一种方法
一
允许此导航,
这个集合
一
在里面
乙
不是由“附加”操作显式管理的
从现在起
一
没有方法对其集合进行变异;
它是在存储库内的基础设施中通过数据库查找和重构实现的。
. 是的,代码模型仍然表示
存在
关系的来源
乙
到
一
,但尚不清楚其来源和计算方法。
我该帮什么忙?更显式的代码模型,它通过“附加”操作管理代码中的双向关联,即使它涉及在同一事务中保持引用同步和改变两个不同的聚合;或者让存储库重构其中一个聚合,检查持久化状态的状态,但将关联的部分语义留在存储库实现中?
更新:更多上下文
简化后的域名与此非常相似:一个有教室、课程和学生的教育中心。学生主要是在另一个BC(个人数据等)管理,但在这里他们也可以变异,因为他们可以随时改变合同/协议(这也是在另一个BC管理),并决定他们可以参加的课程种类。该合同的唯一编号与
Student
实体需要跟踪它们。学生开始上课,但随时可以换到另一门课程,所以所有考勤记录(分数等)属于
学生
实体。
用户与学生见面,并根据当前合同注册学生,但有许多超出能力范围的规则,其中大多数要求探索
学生
,作为以前的任务或出席。业务在这方面有很大的限制,系统目标之一是在不给用户留下很多选择的情况下执行这些规则。可以根据用户的权限选择不同的注册策略。哦,还有很多用户在同一时间和不同的学生执行相同的操作,业务要求用户需要尽可能“最实时”地看到变化。
当然,还有更多的规则,其中一些规则与课程的能力有关,但这只是该领域的一瞥。我两个都是模特,
Course
(之前被引用为
一
)
学生
(以前)
乙
)作为聚合根。为了完成注册用例(“附加”操作)
课程
从其存储库中检索并与域服务协作。
课程
因为另一个用户可以同时修改同一门课程(引发并发异常,必须再次验证规则),所以至少需要当前学生的id来计算其容量;不存在直接引用
学生
从
课程
,仅按ID。的实例
学生
需要检查其当前合同和
课程
已注册,包括“同一注册会话”的注册,以便决定请求的操作结果。