【问题标题】:DDD - Domain Service with infrastructure implementationDDD - 具有基础设施实施的域服务
【发布时间】:2021-01-31 10:33:54
【问题描述】:

我正在使用六边形架构在 DDD 中实施一个项目。 我正在尝试遵循所有避免贫血域模型的最佳实践,但我遇到了这个问题。
我有一个具有属性优先级的实体客户端,为了计算这个优先级,我使用了对外部 API 的休息调用。
我想避免在实体上使用 setPriority 方法,所以我提出了这个解决方案,但我不确定它实际上是否“符合 DDD”。
这里是伪代码:

//DOMAIN
interface PriorityService {
  public int exec(Client client);
}

class Client {
....
  public void calculatePriority(PriorityService service) {
    this.priority = service.exec(this);
  }
}

//INFRASTRUCTURE
class ThirdPartyPriorityService implements PriorityService{
  ...
  public int exec(Client client) {
    int priority = this.externalApi(...);
    return priority; 
  }
}

我发现这种方法集成第三方服务非常简单有效,实体是唯一负责其内部状态一致性的,但我可以轻松集成不同的系统。
有没有更好的方法(最好不使用 setter)?

【问题讨论】:

    标签: domain-driven-design


    【解决方案1】:

    有没有更好的方法(最好不使用 setter)?

    也许吧。考虑:

    设计是我们所做的,是为了得到我们想要的东西,而不是仅仅这样做——露丝·马兰(Ruth Malan)

    是否有“更好的方法”将取决于您的上下文中的“我们想要什么”。

    当 Eric Evans 在 2003 年描述 时,他想要做的事情之一是将域代码与“管道”分开——我们应该能够描述业务而不会被数据库字符串污染,并且交易等等。

    public void calculatePriority(PriorityService service) {
      this.priority = service.exec(this);
    }
    

    谜语:在这个设计中,你如何处理the network is unreliable这个事实?如果您的解决方案将具有弹性,那么您将需要在某个地方使用逻辑来确保系统在网络不可用、远程服务器脱机以进行维护、凭据过时等时能够正常运行......

    用不同的方式表达同样的想法:从 Web 服务器获取 HTTP 响应是 I/O,而 I/O 会“污染”所有接触它的东西。因此ThirdPartyPriorityService 是I/O,因此Client::calculatePriority 是I/O。

    同样的想法:我们的 HTTP 客户端必然存在于“命令式 shell”(Bernhardt 2012) 中,通过将客户端注入到我们的域代码中,我们实际上使域代码成为命令式 shell 的一部分。

    另一种方法是识别ThirdPartyPriorityService 正在从某个远程位置检索信息_,也许这个问题确实属于应用程序,而不是域——您的域代码关心信息是什么,但不关心它来自哪里。

    例如,您可以更改您的实现,以便应用程序调用优先级服务,然后将优先级传递给域模型。请参阅协议库上的Cory Benfield's 2016 talk

    以这种方式设计代码并不比另一种更好或更差;这是一组不同的权衡。

    如果我们未能使我们的计划与我们当时理解的思考财务对象的正确方式保持一致,那么我们将不断地因这种分歧而绊倒,这会使我们放慢脚步 --Ward Cunningham, 2009

    如果代码实际上按照您不看它时的想法运行,那么您对更改它的估计可能会更好。这可能是有价值的“我们想要的”。

    【讨论】:

    • 感谢您的回答。我省略了大部分代码库,实际上在 InfrastructureException 到 Domain Exception 之间有一些映射,我也有一个后备策略,但我把它遗漏了,因为我的主要目的是保持域模型的一致性,并找出这种方法是否违反了“如果我的架构是 DDD 纯度”
    猜你喜欢
    • 2021-01-08
    • 2010-11-25
    • 1970-01-01
    • 1970-01-01
    • 2014-06-16
    • 2010-10-16
    • 1970-01-01
    • 2018-07-03
    • 2015-10-07
    相关资源
    最近更新 更多