【问题标题】:Use Case to Command / Application Layer Mapping: Implementation用例到命令/应用层映射:实现
【发布时间】:2018-06-11 17:08:53
【问题描述】:

我读过的一些关于 DDD 的文章表明,应用层中的应用服务或命令 (CQRS) 密切反映了特定的用例。

对于简单的用例,这种映射很有意义,但在需要多个用户交互的更复杂的情况下,我试图了解如何映射 API 的更粗粒度级别,而不将应用程序逻辑推入 UI。

示例: - 想象一个应用服务:

ImportProductData(date_source)
  • 从系统/UI 的角度来看,在导入产品数据时,我们希望检查是否有任何产品已经存在,如果存在,则在继续之前提示用户是否要继续。

我通常的做法: 扩展 API 以包括:

DoesIncludeExistingProducts(data_source)

如果返回true,提示用户是否要继续,然后调用。

ImportProductData(date_source, overwrite=True)

我的问题是,这是否会将大部分应用程序逻辑转移到 UI 层? (即 UI 现在正在控制是否可以覆盖产品,以及在导入产品数据之前是否应检查现有产品等)

如果是,我无法想象应用程序层和域层将如何处理这个问题?除了:

调用:

ImportProductData(date_source)

如果失败,检查失败的原因,如果由于产品已经存在,提示用户并再次调用:

ImportProductData(date_source, overwrite=True)

这感觉就像做与上面相同的事情的不同方式。

这可能看起来有点迂腐,但我正在努力使表示层 (MVC) 尽可能轻薄。

关于更优雅的解决方案的想法?


【问题讨论】:

    标签: user-interface architecture domain-driven-design ddd-service application-layer


    【解决方案1】:

    首先查看 Jimmy Bogards 的启发性帖子 https://jimmybogard.com/domain-command-patterns-validation/。他没有回答你的问题,而是以一种能让你更容易下定决心的方式攻击它。

    在那篇文章中,他简要地谈到了我认为需要更多关注的一点。如果“用户经常尝试做我的域验证不允许的事情”,他建议不要使用异常作为通信机制。使用这个标准,我更喜欢将预期有时会失败的用例分解为验证调用,然后是执行调用。

    在您的情况下,使用 IsProductSetValidForImport 等验证查询(而不是命令)似乎是合适的。在上面 Jimmy 的文章中,他很难确定返回的错误集应该有多丰富,但是查询的返回集应该是丰富的,所以我们没有问题。您可以返回一个真实的、完全形成的视图模型来显示给用户,而不是试图将足够的数据塞进一个错误字符串中来绘制屏幕。我假设如果 10 个产品中有 3 个无法导入,您可能希望允许用户强制更新某些产品而不是其他产品。这给了你这个机会。

    如果这个验证查询没有返回冲突,给用户一个“你确定”的消息,然后调用 API 来执行导入命令。如果在调用验证查询和发出更新命令之间发生了一些重要的状态变化,那么抛出异常并处理后果是合适的。

    【讨论】:

    • 感谢 Brad 提供精彩文章的链接和周到的回复。您的回复证实了我倾向于的方向,因为这是在发出命令本身之前需要的查询实例(您的描述中的验证查询)。然后,如果这是用户响应,系统可以通知 API 强制更新到查询结果。退后一步,现在感觉查询和命令本身之间的分离非常明显!
    【解决方案2】:

    在用户发出真正的命令来做一些可能会改变事情的事情之前,您不应该访问 ApplicationServices。

    是什么阻止了您在 MVC 表示模式中让控制器使用 ViewServices 层来完成您所要求的事情?

    【讨论】:

    • 谢谢。同意 ApplicationServices 不应该收到任何东西,直到发出真正的命令。就 ViewServices 层而言……是的,这绝对可以在这里。但是我们可能会考虑在未来添加另一个界面(GUI),在这种情况下我们需要复制这个逻辑。因此试图更好地理解如何将其从 PL 中移开。
    • @Steven。好吧...如果您的新 GUI 将使用应用程序服务层;是什么阻止您在新的 GUI 中使用已经创建的 View Services 层?
    • 是的,我明白了。我最初读到暗示该层将成为控制器的一部分。但我误解了。创建一个 View Services 层肯定是一种选择。
    猜你喜欢
    • 1970-01-01
    • 2020-09-20
    • 1970-01-01
    • 2020-02-20
    • 2011-06-04
    • 2016-06-05
    • 2011-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多