【问题标题】:Domain Driven Design (DDD): A Domain or Infrastructure Concern领域驱动设计(DDD):领域或基础设施问题
【发布时间】:2018-07-03 15:11:44
【问题描述】:

我正沉浸在 DDD 中,并且有一个关于什么属于域以及什么是基础架构问题的问题。

描述域的简化示例:

应用程序中的一个上下文是关于允许用户检查网页以获取某些信息的便利功能。即..

“用户想要检查网页并确定短语“lorem ipsum”是否出现以及出现在什么位置。”

我们将使用 Selenium 作为匹配短语的底层技术。

在深入研究 DDD 之前,我会创建一个如下所示的类(下面是 Python,但语言无关紧要):

class Page:
def __init__(self, url, environment, driver):
    self.environment = environment
    self.url = url
    self.driver = driver    // Selenium Driver


def contains_phrase(self, phrase):
    self.driver.get(self.environment.url + self.url_suffix)  // Selenium Command
    ...

这个实体现在依赖于 selenium,不再是一个纯对象(PO​​CO、POJO 等)。在 DDD 中我觉得这不正确。

我的理解是,selenium 表达式也不属于 Application Service 层,因为这会使类/方法膨胀,并且服务层理想情况下应该很薄。

这是否属于基础设施层?很像一个带有持久性代码的存储库。比如:

class PageAutomator:
...
def does_page_contain_phrase(self, page, phrase):
    self.driver.get(self.environment.url + self.url_suffix)  // Selenium Command

这听起来像正确的方向吗?如果是这样呢?:

这意味着 Page 实体开始趋向于贫乏模型,并且正在成为一个简单的 DTO。如果是这样,这个实体是否还有必要?

应用程序服务层是否可以直接调用基础设施层并执行一些操作(以执行用例)而不涉及任何实体(以及域)?即使采用更多的事务脚本方法,我的理解是 Selenium 功能仍然不应该存在于域中?

或者(我是 DDD 的新手)我完全脱离了基础,在这种情况下,非常欢迎任何建议或建议。

谢谢

【问题讨论】:

  • ...并且不再是纯对象(PO​​CO、POJO 等)。 DDD 与 POCO 或 POJO 无关(除非您使用 cqrs/es),它的关于实体的行为。根据其定义,POCO/POJO 不包含依赖项和没有行为。因此,它与您对 DDD 的需求相反(当然,命令、查询和事件消息除外)。经验法则:如果它需要依赖项(数据库访问等),则它不属于您的域聚合。通常你抽象基础设施(MVC、UI、数据库框架)并在你的域中使用抽象接口(或你的语言中的等价物)
  • @Tseng 看起来您将 POJO 与 DTO 混淆了。 POCOs/POJOs 实际上可以有行为。
  • @guillaume31: POCO: 本质上,POCO 对外部框架没有任何依赖,通常没有任何附加行为。 i> 具有行为的模型在 DDD 的上下文中通常称为富域模型
  • @Tseng 不,这是一种误解。请阅读关于 POJO 的 Wikipedia 文章,它基本上与 POCO 上的文章相反。
  • 在 DDD 的上下文中,POCO 一词历来与实体的持久性无知的概念相关联。实体确实有行为。例如,请参阅此答案:stackoverflow.com/a/13632709/329660

标签: python architecture entity domain-driven-design ddd-service


【解决方案1】:

在 HTML 中搜索字符串不是业务逻辑,因此域驱动设计不应该在这里应用。

一个 DTO 或一个没有行为代表页面的类在这里是有意义的。

如果需要对 Selenium 特定实现或跨应用程序的可重用性进行抽象,“搜索服务”将是一个基础架构问题。如果不需要,那将是特定于应用程序的服务/实用程序。

【讨论】:

  • 谢谢德米特里。是的,这就是我要着陆的地方,但是阅读了一些回复以使其直截了当。我们确实有“测试”和“套件”的概念,用户可以构建、合并和应用到不同的平台和环境,这更适合领域。 Page 类是对 Selenium 的抽象,用于在技术上执行测试,因此 Infrastructure 对我来说很有意义。
【解决方案2】:

我的理解是,selenium 表达式也不属于 Application Service 层,因为这会使类/方法膨胀,并且服务层理想情况下应该很薄。

是的,你是对的。 Selenium 表达式应保留在基础架构中,因为它们是特定于技术的。

这意味着 Page 实体开始趋向于贫乏模型,并且正在成为一个简单的 DTO。如果是这样,这个实体还需要吗?

如果域是贫血的(请阅读“简单”),那么模型也将是贫血的。

当我们考虑应用程序的写入部分时,贫血就有意义了,当行为应该留在聚合中时,它应该留在域服务中。

如果是这样,这个实体还需要吗?

如果你的事物有一个生命周期(它有一个身份;它被创建、修改然后死亡)那么是的,一个实体是必要的。如果行为缺失(因为域很简单),您可能拥有一个 CRUD 实体而不是一个成熟的 DDD 聚合。您可以做出其他战略或战术 DDD 决策(如限界上下文和上下文映射)。

应用服务层是否可以直接调用基础设施层并执行一些操作(以执行用例)而不涉及任何实体(以及域)?

是的。

【讨论】:

  • 感谢康斯坦丁。你的回答很有道理。根据我上面的评论,测试套件和测试用例(与代码测试无关)的概念更有可能属于该领域。带有 Selenium 的 Page 对象是应用程序服务层可以用来执行测试的实现和技术特定的关注点。测试在从构建到失败再到通过等过程中都具有身份。抱歉,最初没有提供此详细信息。有时需要指出显而易见的事情!
猜你喜欢
  • 2021-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-30
  • 1970-01-01
  • 2014-06-16
相关资源
最近更新 更多