【问题标题】:Can controllers act as Application Service layer in DDD? [duplicate]控制器可以充当 DDD 中的应用服务层吗? [复制]
【发布时间】:2017-05-18 21:11:20
【问题描述】:

在 ASP.NET MVC 世界中,控制器是否可以充当应用程序层,调用我的域对象和服务来完成工作(假设控制器只是严格调用域并且什么都不做)。在处理的特定情况下,我需要建模的应用程序流逻辑非常少,因此我正在考虑取消应用程序层并直接从控制器内调用域。

这是一个公平的方法吗?

【问题讨论】:

  • 只要您了解设计的含义,就没有关于您可以做什么和不能做什么的明确规定。它总是归结为成本收益权衡。在这种情况下,简单性是以牺牲灵活性为代价的。例如。如果你有多个用户界面怎么办?如果外部系统必须与您的应用程序交互怎么办?我通常更喜欢立即添加额外的间接层,因为它不是那么昂贵,并且可以为您节省大量重构。
  • 人们过于关注这些设计模式。它们是模式,因为它们解决的问题足够普遍,以至于许多人最终会一遍又一遍地做相同类型的事情。但是,并非每个应用程序都需要每种模式。根据您的应用程序的需要设计您的应用程序,而不必担心您是否检查了设计模式清单上的所有框。
  • @plalx:现在添加一个额外的间接层现在对我来说似乎有点矫枉过正,不过我完全理解你的情况。我愿意保持简单,因为知道引入另一层的成本是有代价的。
  • @Chris 我不得不问这个问题只是为了确保我没有严重忽视任何事情。
  • 我并没有反对它。只是意味着只有您可以说出对您的应用程序来说什么是好主意或不是一个好主意。以最有意义的方式设计它,其他一切都会自行解决。遵循这些模式旨在降低维护成本。但是,实施它们有其自身的开销。为可能永远不会发生的潜在未来而建设,或者只是做现在需要做的事情,这始终是一种平衡行为。最终它总是一个判断电话。

标签: asp.net-mvc domain-driven-design


【解决方案1】:

我猜你的意思是你的业务逻辑是使用领域模型模式实现的。在这种情况下,您的应用程序层应该非常简单,并且根据定义它不应该承载任何业务逻辑。所有业务逻辑都应该驻留在领域层;应用层中的方法应类似于以下步骤:

  1. 加载聚合实例
  2. 执行操作
  3. 保持更新的聚合
  4. 向用户返回响应

如果这就是您在应用程序层中所做的一切,我认为没有理由不将其放入控制器中。

另一方面,如果您的领域模型是贫乏的,并且您在应用程序层中确实有业务逻辑,那么我更愿意引入一个单独的层。

【讨论】:

    【解决方案2】:

    将 MVC 控制器视为 DDD 应用程序层会带来一些负面情况。

    最重要的是,您的应用层(关于 DDD)是您为域/业务流程建模的关键位置之一。例如,您可能在应用程序服务中有一个名为:

    PayrollService.CalculatePayslips();
    

    这可能涉及检查当前在职员工的域服务或外部系统,然后可能需要查询另一个域服务或外部系统的缺勤、养老金扣除等。然后它需要调用域服务 (或实体)来进行计算。

    如果您想从系统的其他地方触发计算工资单的任务,那么在 MVC 控制器中捕获这样的域/业务逻辑会导致架构问题。此外,如果您曾经想将此过程公开为 Web 服务,或者甚至从另一个 MVC 控制器公开,您将有跨越或向上进入您的表示层的引用。像这样的解决方案“可能有效”,但它们将有助于您的应用程序成为意大利面条代码或大泥球(两种代码在架构意义上都闻起来)。您可能会导致循环引用和高度耦合的代码,这会增加未来的维护成本(时间、金钱、开发人员的理智等)。

    说到底,软件开发是一场权衡取舍的游戏。架构问题成为更大的问题,您的应用程序越大。对于许多非常小的 CRUD 应用程序,架构问题可能可以忽略不计。 DDD 的主要目标之一是处理复杂性,因此可以说大多数 DDD 项目应该具有足够的复杂性来关注良好的企业架构原则。

    【讨论】:

    • 我听到了你的担忧,但我是 YAGNI 的忠实粉丝,目前据我所知,我的控制器不需要应用程序逻辑。在我看来,创建一个应用程序层只是因为我可能在功能中需要它,或者因为这是正确的做法,但我并不满意。但我很欣赏你的观点,它确实向我重申了对应用程序服务的需求(我们需要它们的地方)
    • 公平地说,架构决策取决于很多事情,它始终是一种平衡行为。如果它是你自己的应用程序(只是你开发它),它体积小,不太可能增长(或者它的生命周期很短)并且没有其他开发人员必须维护它,那么让事情变得更复杂可能没有任何好处比他们需要的。
    • 还需要考虑单元测试。对控制器进行单元测试通常比一组类库方法更难。同样,如果您只是在试验、编写一个小型应用程序等,您可能会发现对代码进行单元测试没有任何好处。
    【解决方案3】:

    我不会这样做的。

    为应用程序服务创建一个单独的类然后从控制器调用它的工作量很小。成本也仅在您构建应用程序时存在。

    但是,由于业务层和表示层之间的高度耦合,一旦开始维护应用程序,您必须付出的代价要高得多。

    当您确保在应用程序中使用separate different concerns 时,测试、重用、重构等操作会大大降低。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 2011-01-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多