【问题标题】:What is the difference between procedural code and Domain Driven Design style code?程序代码和领域驱动设计风格代码有什么区别?
【发布时间】:2012-08-10 17:08:42
【问题描述】:

我正在学习领域驱动设计 (DDD) 技术,但我觉得我还没有很好地理解它。

DDD 建议将业务逻辑(不是基础设施,如持久性、安全性等)放入域对象、持久性存储库、为客户端(演示)组装域对象的聚合器、域对象之上的薄层服务和存储库、聚合器并充当事务边界。

让我这样说:

在 DDD 中,ViewController --> SomeService --> {Domain Objects, Repositories, Aggregators}

在我目前的(程序风格)方法中: ViewController --> SomeService --> DAO/Repository

这里,ViewController 与一个或多个服务对话,以使用 DAO 从/向数据库拉取/推送数据。如果仅对域对象的属性进行操作的任何业务逻辑将在该域对象本身的方法中。最后,从服务中获取的数据被聚合到 DTO 中以呈现在视图层中。

所以对我来说这两种方法看起来几乎相似。

谁能解释一下我错过了什么?

PS:我正在添加更多信息以更好地解释我的问题。 理论上每个人都在说 DDD 建议“逻辑应该在域对象中”。好的。 让我们来看一个真实的场景。

在 ShoppingCart 应用程序中,一些用户下了订单。要处理订单,我需要执行以下所有子任务:

  1. 获取每个项目的详细信息并计算总订单价格。

  2. 获取收货地址并使用地址验证服务进行验证

  3. 验证/验证信用卡详细信息

  4. 将所有订单相关信息保存到数据库中

所以按照DDD我会放逻辑,

  1. Order 对象中的Order Total 计算,该对象循环遍历其List 对象。

  2. 在地址对象中,我将拥有 validate() 方法,该方法会调用一些 BING 地址验证。

  3. 在 CreditCard 类中,我将拥有 authorize() 方法,该方法调用一些 CCAuthorizationService 来授权使用一些第三方服务。

  4. 使用一些存储库将所有订单内容保存到数据库中。

所有这些步骤都将通过调用 Order.process() 来触发

如果这是正确的 DDD 方法?如果是,我们的域对象直接与存储库交互,这似乎违反了关注点分离。

如果这不是正确的 DDD 方法,有人可以告诉我你是如何为上述用例设计的吗?

【问题讨论】:

  • “仅对域对象的属性进行操作的业务逻辑”是什么意思?您可能缺少 IMO 的是,您当前的方法并不完全是通常所说的程序代码......
  • 我的意思是,如果有任何计算可以得出仅基于一个域对象的属性的某个值,那么执行计算的方法应该只在域对象中,而不是在服务类中。

标签: java oop domain-driven-design ooad


【解决方案1】:

DDD 与语言无关,它是关于通过专家了解领域并构建一种通用语言,您可以使用它来讨论该领域。因此它不能直接与函数式、过程式或面向对象的编程语言进行比较,因为它们没有可比性。

视图控制器特定于 MVC 框架,并不特定于 DDD。

在 MVC 中,用于为视图准备数据的 DTO 是视图模型。

希望这能有所帮助。

【讨论】:

  • 阿德里安,你是对的。 DDD 与语言无关。我期待通过遵循 DDD 方法来实施解决方案的方法。最后,我们需要将这个 DDD 概念转换为正确的代码。您能告诉我您如何处理上述 DDD 风格的 ShoppingCart 场景吗?
  • 我会将您的信用卡授权放入一项服务中,因为这将涉及多个领域对象的合作,并且可能包括工作流类型流程和决策制定。
  • 您的前 2 个项目不需要任何存储库访问权限。我希望创建对象很可能归结为某种工厂,而“保存”方面将是您可以在域实体/对象中执行的操作。在架构上,您可能最好考虑使用 IOC 容器在构造函数中通过接口注入存储库。
  • 因此,如果任务涉及流程的工作流样式并涉及多个域对象的协作,那么您更愿意将此工作流放在服务中。在这种情况下,似乎 DDD = 正确编写的程序样式方法,其中域对象具有对自身属性进行操作的业务逻辑方法。休息就像程序风格的服务,存储库一样。从域对象与存储库交谈是否很好?
  • 从域实体访问存储库通常在架构上很尴尬。在这篇文章中有一些很好的答案:stackoverflow.com/questions/827670/…
【解决方案2】:

归结为逻辑所在的位置。在 DDD 中,逻辑主要进入模型层,因此它靠近数据。在过程代码中,逻辑进入事务层,因此它与数据分离。 Fowler 有一个很好的描述,你可以阅读 here

【讨论】:

    【解决方案3】:

    它们相似的。

    希望您实际上是在将“OOP”与“DDD”进行比较。 DDD 是 OOP (IMO) 的子集,或者至少应该在 OOPL 中。 DDD 是一种分解职责的特定思维方式。

    【讨论】:

      【解决方案4】:

      这与技术或 OOP 或类似的东西无关。 它是关于关注手头的领域、领域专家使用的语言、理解领域并对该领域进行建模,以便在代码中呈现重要的概念。

      它最初是使用 OOP 完成的,许多人声称它只能使用 OOP 完成。 然而,最近像 Greg Young 这样的人已经展示了如何在函数式语言中进行 DDD,并且仍然专注于该领域。

      程序代码倾向于忽略所有这些,只关注如何从任何数据源读取/写入数据。例如与 Movex 之类的系统集成后,将有十亿个表和列的名称完全滞后,例如 TAXEM.YAROOD FOOB.AAR,这对于阅读该代码的任何人来说都毫无意义......

      【讨论】:

        猜你喜欢
        • 2022-11-02
        • 2022-01-25
        • 2020-04-27
        • 2011-01-07
        • 1970-01-01
        • 2011-12-24
        • 1970-01-01
        • 1970-01-01
        • 2014-02-11
        相关资源
        最近更新 更多