如何在DDD中建模瞬态?

时间:2016-02-17 21:04:46

标签: domain-driven-design

我刚刚开始使用我的第一个域驱动设计项目。该项目的领域模型涉及有界上下文,处理位于三维场景中的移动几何的碰撞检测。

业务逻辑的核心部分是碰撞检测算法,即 CollisionDetector 。该算法必须配置一些影响其行为和性能的参数。所以它有一些附加状态让我把它想象成一个实体,或者说首先是一个聚合体。请注意,不需要将此实体持久保存到DB - 其所有参数值都是瞬态的。另请注意,域中只存在一个 CollisionDetector 实例,因此实现内存存储库可以访问该单个聚合对我来说有点过头了。

总结一下,我们有一个具有单身性质的有状态的瞬态实体

所以这是我的问题:正常"正常" DDD中的聚合应始终通过存储库访问,我应该如何处理这样一个独特的实体实例?

  • 建议在这里使用(邪恶)单身人士模式吗?
  • 我是否应该向我的IOC注册该实体?
  • 我应该实现一个内存存储库来保存该单个实例吗?
  • 将它建模为实体是否合理? (它并不需要它的独特性。)
  • 我应该重构以使其成为(有状态的!)域名服务吗?
  • 域模型的设计气味是否有这种类型的多个聚合?
  • 我听说过Sagas。他们可以解决我的问题吗?

如果您需要更多背景信息来帮助我解决此问题,请立即告诉我。

P.S。请原谅我破碎的英语。我不是母语人士。

修改

我觉得我应该对CollisionDetector班级以及附属于该州的州提供更多详细信息。

也许称之为 transient 是误导性的。我的意图是指出CollisionDetector永远不会被保存到存储中。它的整个生命都花在了积极的记忆中。创建,修改和删除都是其生命周期的一部分,持久性不是。

CollisionDetector的另一个重要品质是我所称的单身性,这意味着CollisionDetector只会实例化一次(但不一定使用GoF Singleton模式)。我不确定身份的概念是否适用于单例实例(至少不需要识别,因为只有一个),这是阻止我使CollisionDetector成为实体/聚合的唯一因素

因此,让我根据@plalx,@ guillaume31和@arootbeer的要求阐明CollisionDetector的状态。

  • 如上所述,有一组简单的标量参数值用于调整算法,使其更准确或更快。用户可以随时调整这些参数以满足他的需求。
  • CollisionDetector会跟踪场景中的几何形状及其姿势。这是通过域事件实现的:当其中一个几何图形改变其姿势时,事件处理程序将自动触发碰撞测试。同样,新检测到的冲突也由CollisionDetector通过域事件发布。请注意,并非所有几何都被视为碰撞候选,用户可能会从测试中排除其中的一些。因此CollisionDetector拥有几何id的黑名单(其状态的一部分)。
  • 为了实时检测碰撞,该算法需要预处理,该预处理在CollisionDetector的单独初始化例程中完成。每当在场景中添加或删除几何体时,预处理都会变得陈旧并需要刷新。 CollisionDetector知道这一点,即它知道是否需要重新初始化。

希望这有帮助!

重新思考我的问题我必须承认它只是学术性的。一个实用的解决方案可能是使CollisionDetector成为聚合,并将其注册到IoC容器中。你觉得怎么样?

1 个答案:

答案 0 :(得分:2)

  

算法必须配置,其中包含一些影响其行为和性能的参数。因此,它附加了一些状态,这使我首先将其视为一个实体或者更确切地说是一个聚合体。 (强调我的)

我不认为CollisionDetector的配置是其状态。它只是配置,并且在实例化CollisionDetector后无法更改,因此它通常比您在实体中找到的可变状态简单得多。

因此,我清楚地认为CollisionDetector域名服务。这意味着你应该按如下方式处理它:

在IoC中注册CollisionDetector服务。 CollisionDetector的配置可能被视为域逻辑,因此在CollisionDetector中实例化CollisionDetectorFactory是有意义的。如果您采用这种方法,请在IoC中注册工厂。在任何情况下,请确保CollisionDetector的客户不必了解其配置。< / p>

顺便说一句,在使用IoC时,不要使用单例(即GoF单例模式)。您始终可以将服务注册为单个实例,其效果与单例模式相同,但可以避免出现问题。