有一个服务器列表。每个服务器都有自己的玩家列表。玩家名单以及服务器数据会定期更改。为每个玩家保留单独的统计数据。
为了收集有关服务器和玩家的信息,我创建了一个单独的上下文。决定申请CQRS。
为了显示统计信息,我创建了一个单独的读取模型。这里的一切都很简单——通常的读取操作。
有一个关于信息记录领域的问题。
接收统计数据处理时最好应用什么:
使用一组聚合、事件和其他战术模板形成一个成熟的领域模型
使用普通交易脚本(Transaction Script)
我倾向于使用事务脚本:
- 易于实施
- 海量数据一次性更新
在这种情况下使用DDD让我感到困惑:
- 我无法想象在处理统计信息时使用 DDD 方法——可能有大量抽象
- 存储库涉及一次编辑一个聚合。假设我的服务器播放器是具有相应统计信息的单独聚合。如果需要更新大量玩家的信息,数据库的负载会很大。
另一方面:
DDD 将允许您正确封装数据验证逻辑。
随着时间的推移,事务脚本很难维护。
我真的需要你的建议)
当您拥有丰富的主题领域时,DDD 方法非常适合:文档的移动、法规、同一业务场景中不同实体的交互。数据处理任务,尤其是较快的数据处理,不太适合 DDD,因为其中的逻辑比较简单,SQL 足以解决。
也就是说,DDD 过于复杂,无法解决如此简单的问题。此外,DDD 可能不是一种非常高效的方法,因为例如它涉及加载整个聚合。
这是一方面。另一方面,DDD 方法不是一套硬性规定,而是一套原则。我们可以为数据处理分配一个有界上下文,其中模型将比主上下文中的模型更简单。
存储库一次只能处理一个聚合的规则实际上并不存在。存储库 是一个超大的集合,因此我们不能直接使用它的所有元素,只能使用一些小片段。这就是 Evans 定义存储库的方式。
如果主题领域规定,存储库可能包含用于批量插入、删除和修改数据的方法。相反,您需要注意这样一个事实,即每次这样的调用都执行得很快,也就是说,您不能创建一个方法来更新数据库中的所有记录,可能是几百万。相反,我们需要一种批量(页面)更新的方法,而每批的大小可以是 100 或 1000 条记录。
用于解决统计问题的实体没有行为,因此在我们有限的上下文中,我们使用贫血域模型模式。必须记住,它通常被认为是一种反模式,这是相当公平的。但在这种特殊情况下,这是正确的决定,因为事实上,我们必须在数据库中对数据进行切片,并借助关系代数的一些操作将其缩减为几张表。
第二种方法我不仅仅定义为事务脚本。最终,我们可以使用专门的工具来准备报告,该工具将具有对数据库的读取权限,即某种 Microsoft Reporting Services。我们可能必须在相邻数据库中聚合中间数据,以便以后更快地生成报告,我们将在 SQL 中执行此操作。
一般来说,我们没有义务在 DDD 和 OOP 的框架内做出所有决定。他们甚至不需要使用 Java/C#/Python 项目的主要语言来完成。在这里,团队的技能起着决定性的作用。
我要对这样一个系统添加的唯一限制是统计应用程序不得更改主数据库中的数据。它具有只读访问权限,如果它需要自己的中间数据,它会将它们存储在单独的模式或单独的数据库中。此限制将使您避免出现细微的错误。
全部的:
如果您的整个团队主要使用 Java/C#/替代您的语言编写,那么请尝试使用贫乏模型和强大存储库的有限上下文。
如果有人在 SQL / Reporting Services 等方面摸不着头脑,您可以单独制定解决方案。它可能比在 Java/C# 中做同样的事情更快、更方便。
中间解决方案:您可以使用 Java/C# 制作专用解决方案,但需要最少的 OOP。您可以使用简单的数据访问模式:行网关、表网关、事务脚本等。
无论您选择哪个选项,都不要从第二个解决方案写入主库,以避免难以查找和修复的错误。只读访问主数据库,只有主上下文可以改变它。