【问题标题】:domain driven design behaviours and services领域驱动的设计行为和服务
【发布时间】:2014-04-25 13:00:20
【问题描述】:

我是域驱动设计的新手,并试图弄清楚应该把什么放在哪里。假设我有一个名为 Order 的类和一个名为 OrderDto 的相关 DTO。

前端通过传递 OrderDto 调用 OrderController(MVC 架构),控制器调用 OrderService。

然后我使用 OrderRepository 从数据库中获取订单并使用 OrderDto 更新订单。假设我想每次计算总、增值税和小计,客户添加/编辑订单。问题是,在 DDD 中我应该将这些计算放在哪里。

  1. 在服务层中作为私有方法(例如 RecalculateTotal)或在辅助类中作为静态方法
  2. 在行为类中
  3. 域内部(类成员设置器)

目前我在服务层执行此操作,但我确定我错过了一些东西。因为每次用户从他的订单中添加或删除产品时,我都必须手动调用我的重新计算方法。我认为这个计算应该自动完成。所以我不必/不需要担心这些计算。

任何帮助将不胜感激。

更新 1
总而言之,我们应该将业务规则放在 DDD 的哪个位置?

【问题讨论】:

    标签: asp.net-mvc design-patterns domain-driven-design repository-pattern


    【解决方案1】:

    “如果规则存在是因为业务需要,那么它属于域”

    本着 DDD 的精神,将所有计算都放在您的域中。

    域有时被称为“业务层”是有原因的,因为它包含所有相关的业务逻辑/规则。

    以下代码是纯 DDD 的示例。每次添加订单时都会自动完成总计算,您不必担心忘记显式调用“计算例程”。

    public class Order
    {
        public void AddItem(Item item)
        {
            // Do add item here
            this.CalculateTotal(); // At the end, calculate total.
        }
    
        private void CalculateTotal()
        {
            // Do calculations
            this.Total = 0; // after calculations, assign new value;
        }
    
        public decimal Total { get; private set; } // notice the "private" setter?
    }
    

    您不必担心计算,让您可以将精力集中在其他事情上。

    如果您需要更改计算,您只需转到包含业务逻辑的地方即可。欢迎来到领域驱动设计^_^

    更新

    以下是针对增值税评论的更新代码。

    增值税

    同样,增值税的计算是在 CalculateTotal() 内自动完成的

    如果增值税取决于每个国家/地区,则只需创建一个具有增值税属性的国家/地区。将 country 属性放在 Customer 上,如下所示:

    public class Customer
    {
        public Country Country { get; set; }
    }
    
    public class Country
    {
        public string Name { get; set; } // Country Name
        public decimal Vat { get; set; }
    }
    

    CalculateTotal() 中,只需根据客户所在的国家/地区检查他们是否受到增值税的影响。

    public class Order
    {
        public void AddItem(Item item)
        {
            // Do add item here
            this.CalculateTotal(); // At the end, calculate total.
        }
    
        private void CalculateTotal()
        {
            // Do calculations
    
            // Get Vat
            decimal vat = this.Customer.Country.Vat;
            this.Total = 0; // after calculations, assign new value;
        }
    
        public Customer Customer { get; set; }
        public decimal Total { get; private set; } // notice the "private" setter?
    }
    

    如果您打算更改增值税,那么您知道去哪里找(当然是国家)

    增值税的任何变化都会影响该国家/地区的所有客户。

    【讨论】:

    • 嗨,Yorro,感谢您的回复。还有一件事要澄清。假设我需要为总额添加增值税。在添加增值税之前,我需要检查我是否可以为该客户申请增值税。我认为 CanApplyVAT 应该是一种行为。那正确吗?如果是我可以在域中调用我的行为吗?你怎么看
    • 谁来决定这个客户是否有增值税?它是客户的财产吗?
    • 是的,比如说国家。英国客户必须有增值税,而美国客户则不能。
    【解决方案2】:

    我更喜欢创建 OrderCaluclate 接口和所需的方法,如“calculateTotal”、“calculateVAT”等...然后我创建不同的订单计算,并使用策略设计模式创建 Order 和 OrderCalculate 之间的关系。

    通过这种方式,您还可以灵活地计算订单,例如某些订单计算所需的一些附加参数。

    【讨论】:

    • 感谢 Kumar,我必须阅读有关策略设计模式的内容并弄清楚这就是我要寻找的。​​span>
    • 您可以从这里获取详细信息“oodesign.com/strategy-pattern.html
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    • 1970-01-01
    相关资源
    最近更新 更多