首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >上下文域驱动模型验证

上下文域驱动模型验证
EN

Stack Overflow用户
提问于 2013-05-06 22:00:47
回答 2查看 395关注 0票数 2

在我们的应用程序中,我们有一个场景,其中我们需要基于业务规则和当前用户的上下文来验证属性更新。我正在尝试确定进行验证的最佳方法,因为我认为域模型不应该知道当前用户。我们的正常授权与域是分开的,并且与此场景不同。

验证应该在哪里进行,有没有更好的方法来处理它?域模型应该知道用户的情况吗?如有任何帮助或建议,我们将非常感谢。

简单的例子:我们有一个具有批准数量的订单。只有特定用户类型才能在特定方向上更新数量。这是在域聚合中验证的正确方式吗?

代码语言:javascript
复制
public enum UserType
{
    ViewUserType,
    RequesterUserType,
    SupplierUserType
}

public class Order
{
    public int OrderId {get; private set}
    public int RequestedQuantity {get; private set}
    public int ApprovedQuantity {get; private set}

    public void RequestQuantity(int quantity, UserType userType)
    {
        if (userType == UserType.RequesterUserType)
        {
            this.RequestedQuantity = quantity;
        }
    }

    // Question: The direction that the approved quantity can change is a business rule
    // but directly deals with the context of the user.  Should the model know about the user
    // or should this validation be pulled out to either the application service, a model extension,
    // or maybe a specification?
    public void ApproveQuantity(int quantity, UserType userType)
    {
        if (userType == UserType.RequesterUserType)
        {
            if (quantity <= this.ApprovedQuantity)
            {
                // Requester type user can only update if lowering the approved quantity
                this.ApprovedQuantity = quantity;
            }
        }
        else if(userType == UserType.SupplierUserType)
        {
            if (quantity >= this.ApprovedQuantity)
            {
                // Supplier type user can only update if increasing the approved quantity
                this.ApprovedQuantity = quantity;
            }
        }
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-05-11 15:55:56

这稍微受到了Yves的回答和你的回复的启发。

我个人的信条是让隐含的东西变得明确,因为我喜欢应用这个原则后代码的结果:

代码语言:javascript
复制
public interface IProvideCurrentIdentityRoles
{
   bool CanRequestQuantity()
   bool CanApproveQuantity();
   bool CanOverruleQuantityOnSubmittedOrder();
   bool CanIncreaseQuantityOnFinalOrder();
   bool CanDecreaseQuantityOnFinalOrder();
}

public class Order
{
    public int OrderId {get; private set}
    public int RequestedQuantity {get; private set}
    public int ApprovedQuantity {get; private set}

    public void RequestQuantity(int quantity, IProvideCurrentIdentityRoles requester)
    {
        Guard.That(requester.CanRequestQuantity());
        this.RequestedQuantity = quantity;
    }

    public void ApproveQuantity(int quantity, IProvideCurrentIdentityRoles  approver)
    {
        if (quantity == this.RequestedQuantity)
        {
           Guard.That(approver.CanApproveQuantity());
        }
        else 
        {
           if (orderType == OrderType.Submitted)
           {
              Guard.That(approver.CanOverruleQuantityOnSubmittedOrder());
           }
           else if (orderType == OrderType.Final)
           {
              if (quantity > this.ApprovedQuantity)
              {
                 Guard.That(approver.CanIncreaseQuantityOnFinalOrder());
              }
              else 
              {
                 Guard.That(approver.CanDecreaseQuantityOnFinalOrder());
              }
           }
        }
        this.ApprovedQuantity = quantity;
     }
}
票数 2
EN

Stack Overflow用户

发布于 2013-05-07 04:44:07

与其拥有这种类似枚举的类型(UserType),为什么不将这些角色演变成完全成熟的对象呢?你关心的是用户扮演的角色,而不是特定的用户。这将用户确实是提供者或请求者的身份验证和验证推送到上面的层(实际上是调用代码,在本例中可能是某种应用程序服务)。下面是一个非常粗糙的,第一次迭代的可能是什么样子:

代码语言:javascript
复制
public class Order {
  public void RequestQuantity(int quantity, UserType userType)
  {
    this.RequestedQuantity = quantity;
  }

  public void ApproveToLowerOrEqualQuantity(int quantity) {
    if (quantity <= this.ApprovedQuantity)
    {
      // Requester type user can only update if lowering the approved quantity
      this.ApprovedQuantity = quantity;
    }
  }

  public void ApproveToHigherOrEqualtQuantity(int quantity) {
    if (quantity >= this.ApprovedQuantity)
    {
      // Supplier type user can only update if increasing the approved quantity
      this.ApprovedQuantity = quantity;
    }
  }
}

//Calling code
public class ApplicationServiceOfSomeSort {
   public void RequestQuantity(UserId userId, OrderId orderId, int quantity) {
     var requester = requesterRepository.FromUser(userId);
     requester.MustBeAbleToRequestQuantity();

     var order = orderRepository.GetById(orderId);
     order.RequestQuantity(quantity);
   }

   public void ApproveQuantityAsRequester(UserId userId, OrderId orderId, int quantity) {
     var requester = requesterRepository.FromUser(userId);
     requester.MustBeAbleToApproveQuantity();

     var order = orderRepository.GetById(orderId);
     order.ApproveToLowerOrEqualQuantity(quantity);
   }

   public void ApproveQuantityAsSupplier(UserId userId, OrderId orderId, int quantity) {
     var supplier = supplierRepository.FromUser(userId);
     supplier.MustBeAbleToApproveQuantity();

     var order = orderRepository.GetById(orderId);
     order.ApproveToHigherOrEqualQuantity(quantity);
   }
}

诚然,这个API周围仍然有很多“臭味”,但这是一个开始。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16400405

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档