gpt4 book ai didi

domain-driven-design - 用 DDD 连接点

转载 作者:行者123 更新时间:2023-12-04 08:21:01 29 4
gpt4 key购买 nike

我读过 Evans、Nilsson 和 McCarthy 等书,了解领域驱动设计背后的概念和推理;但是,我发现很难将所有这些放在一个真实世界的应用程序中。缺乏完整的例子让我摸不着头脑。我找到了很多框架和简单的示例,但到目前为止还没有真正展示如何在 DDD 之后构建真正的业务应用程序。

以典型的订单管理系统为例,以订单取消为例。在我的设计中,我可以看到一个带有 CancelOrder 方法的 OrderCancellationService,它接受订单 # 和一个原因作为参数。然后它必须执行以下“步骤”:

  • 验证当前用户是否具有取消订单所需的权限
  • 从 OrderRepository
  • 中检索具有指定订单号的订单实体
  • 验证订单是否可能被取消(服务应该询问订单的状态以评估规则还是订单有一个封装规则的 CanCancel 属性?)
  • 通过调用 Order.Cancel(reason)
  • 更新 Order 实体的状态
  • 将更新的订单保存到数据存储
  • 联系 CreditCardService 以恢复已处理的任何信用卡费用
  • 为操作
  • 添加审核条目

    当然,所有这些都应该发生在一个事务中,并且不应该允许任何操作独立发生。我的意思是,如果我取消订单,我必须恢复信用卡交易,我无法取消并且不执行此步骤。这,imo,建议更好的封装,但我不想在我的域对象(订单)中依赖 CreditCardService,所以这似乎是域服务的责任。

    我正在寻找有人向我展示如何/应该如何“组装”的代码示例。代码背后的思考过程将有助于让我为自己连接所有的点。谢谢!

    最佳答案

    您的域服务可能如下所示。请注意,我们希望在实体中保留尽可能多的逻辑,从而使域服务保持精简。另请注意,没有直接依赖于信用卡或审计员实现 (DIP)。我们只依赖于在我们的域代码中定义的接口(interface)。稍后可以将实现注入(inject)应用程序层。应用层还将负责按数字查找订单,更重要的是,负责将“取消”调用包装在事务中(回滚异常)。

        class OrderCancellationService {

    private readonly ICreditCardGateway _creditCardGateway;
    private readonly IAuditor _auditor;

    public OrderCancellationService(
    ICreditCardGateway creditCardGateway,
    IAuditor auditor) {
    if (creditCardGateway == null) {
    throw new ArgumentNullException("creditCardGateway");
    }
    if (auditor == null) {
    throw new ArgumentNullException("auditor");
    }
    _creditCardGateway = creditCardGateway;
    _auditor = auditor;
    }

    public void Cancel(Order order) {
    if (order == null) {
    throw new ArgumentNullException("order");
    }
    // get current user through Ambient Context:
    // http://blogs.msdn.com/b/ploeh/archive/2007/07/23/ambientcontext.aspx
    if (!CurrentUser.CanCancelOrders()) {
    throw new InvalidOperationException(
    "Not enough permissions to cancel order. Use 'CanCancelOrders' to check.");
    }
    // try to keep as much domain logic in entities as possible
    if(!order.CanBeCancelled()) {
    throw new ArgumentException(
    "Order can not be cancelled. Use 'CanBeCancelled' to check.");
    }
    order.Cancel();

    // this can throw GatewayException that would be caught by the
    // 'Cancel' caller and rollback the transaction
    _creditCardGateway.RevertChargesFor(order);

    _auditor.AuditCancellationFor(order);
    }
    }

    关于domain-driven-design - 用 DDD 连接点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10574779/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com