繁体   English   中英

DDD:如何为主从屏幕正确设计聚合?

[英]DDD: How to Correctly design aggregates for a master-details screen?

我有一个屏幕,它是标题详细信息,标题是作业主要类别,详细信息是作业次要类别的列表。 我读了很多有关聚合及其边界的文章,但我感到矛盾。 我的要求:-如何建模?

  • 我是否应使用单个聚合 (包含两个实体,JobMajorCategory将是根聚合,JobMinorCategory将是聚合内的实体),因为它们将保存在同一事务中,或者
  • 两个聚合 (一个用于JobMajorCategory,另一个用于JobMinorCategory),因为它们之间没有真正的不变或业务角色

注意:-屏幕上有一个“保存”按钮,可以将所有图形(主+详细信息)保存在一个事务中。 另外,JobMinorCategory不能没有其父代。 请给我建议如何正确设计这些骨料?

您应该考虑设计一种可以满足您的UI考虑的视图模型或等效的DTO。 这使您可以将聚合集中在域上,然后可以通过转换聚合来加载表示形式。 我了解您说您的业务用例正在谈论“单一交易”的方面,但这只是技术细节。

当我们寻求应用领域驱动的设计时,它与技术选择或目标的实现无关。 相反,它是关于对实际业务领域进行建模的。 设计正确的域将不了解UI,也不会受到UI的影响。 为此,我相信您是在说保存操作应该在单个操作中。 这是完全可以的,因为在较高的级别(如UI)上,您的应用程序可以更粗糙,而在堆栈中向下移动时,应用程序可以更细化。

根据您的发言,您可能需要做的是在域和应用程序之间创建一个明确的边界。 通常,这是通过应用程序服务完成的。 这些“说”应用程序和领域,以便它们可以与领域进行对话,但只能与表面DTO /模型进行对话。 有效地隔离您的域可防止域混乱,然后更改UI(绝对会比域本身更频繁地更改)具有隔离层。

靠近用户的代码和工件会更频繁地搅动。 领域是关于与业务运营方式有关的“真相”。 为此,您的UI只是进入您的域的窗口-或更恰当地,通常是它是对域抽象的视图。

编辑以专门解决问题的详细信息。

在您所描述的内容中,我对域知之甚少,无法提供完整而准确的答案。 但是,您的方向正确。 由于没有JobMajorCategory就无法存在JobMinorCategory,因此可以合理地假设JobMinorCategory是实体还是值对象(例如,如果仅仅是文本,并且对其他JobMinorCategories没有其他关系影响)。 您仍然可以使用该前提进行“单一交易”。

为了争辩,假设您有一个MVC应用程序。 您的保存可以关联到常规的“保存”操作。 继而,该控制器然后可以基于有效载荷来确定要做什么。 如果您将JobMinorCategory标记为要删除的队列,且级别低于控制器,则可以遍历所有项目,收集应删除的项目,并将它们注册为删除对象,以用于管理您的Unit of工作。

域不会关心您如何在UI中执行此操作。 但是,您的域可以公开删除JobMajorCategory的方法,该方法将删除所有JobMinorCategories。 当您了解聚合本身时,这就是业务逻辑应该存在的地方。 例如,您的JobMajorCategory应该具有DeleteJobMinorCategory()和AddJobMinorCategory()的方法。 然后,一旦聚合的状态反映了您希望其处于的状态,就可以从更高级别持久化该聚合。 根据您的整体体系结构,这可能来自域服务。

有多种方法可以执行此操作,但复杂度有所不同。 无需了解更多信息,我会假设您想在后端上加载实际的Aggregate并根据用户操作应用更改。 因此,如果您可以检查模型以查看用户是否删除了JobMinorCategory,则可以让域服务检索最新版本的Aggregate,调用RemoveJobMinorCategory()方法(业务逻辑将在其中运行),然后该方法已完成,然后让域服务保留更改后的聚合。 根据模型,您可能会检测到这多次发生-即用户删除了多个JobMinorCategory。 也可以。 您只需多次调用RemoveJobMinorCategory(),然后继续。

如果正确实现,那就是域驱动设计的美丽之处之一。 您将对聚合进行多个操作,如果适用的业务逻辑允许该更改,聚合将成为“守门人”,然后将其持久化。 由于持久性机制也是一个技术细节,因此我们希望将其保留在实际域对象本身之外的一层上。 就像应用程序服务充当UI /应用程序和域之间的桥梁一样,域服务可以充当域对象和技术细节之间的桥梁。

因此,如果您使用诸如Entity Framework之类的东西(通过上下文包含一个工作单元),则将加载您的实体,通过对实体的方法应用更改(部分类是实现此目的的一种方法),然后持久化完成后将其返回。 这样一来,您就可以在单个事务中完成所需的工作。 通常,您将希望将事务限制为单个聚合或至少单个绑定上下文。

创作将以完全相同的方式工作。 您创建JobMajorCategory聚合实例,并通过封装与添加这些实体相关的逻辑的方法来添加JobMinorCategory实体。 一旦构造和/或修改完成,然后提交那些更改。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM