【问题标题】:DDD - Bounded Contexts and Multiple Models?DDD - 有界上下文和多个模型?
【发布时间】:2011-05-30 03:22:26
【问题描述】:

我正在阅读有关 DDD 中的限界上下文的想法,并且我开始意识到我对 Model 在实践中的确切外观没有清晰的了解。 (我什至可能也不知道 Domain 的确切含义。)

让我们看一下流行的电子商务示例:客户浏览产品、添加到购物车、下订单。订单履行人员将订单发货。

是否存在具有多个有界上下文(产品目录上下文、购物车上下文、订单上下文、履行上下文)的大型电子商务域?每个有界上下文是否包含一堆模型(因此产品目录上下文包含产品模型、产品图像、产品评论)?

离我还有多远?

【问题讨论】:

    标签: domain-driven-design bc


    【解决方案1】:

    至少你在正确的轨道上。典型的错误是只看到模式。

    领域意味着您正在处理的问题(支持电子商务、医疗保健、会计等)。领域模型是尽可能接近我们的心智模型的代码中表示的那些问题的解决方案。

    让我们看一下流行的电子商务示例:客户浏览产品、添加到购物车、下订单。订单履行人员将订单发货。

    在您的示例中,我将从以下内容开始:

    class Product { }
    
    class Customer
    {
        Cart Cart;
        void PlaceAnOrder()
        {
            order = new Order(Cart.Products);
            Orders.Add(order);
            Cart.Empty(); //if needed
        }
        Orders Orders;
        Orders UnfulfilledOrders()
        {
            Orders.Where(order => !order.IsFilled);
        }
    }
    
    class Cart
    {
        void AddProduct(product)
        {
            Products.Add(product);
        }
        void Empty()
        {
            Products.Clear();
        }
    }
    
    class Order
    {
        bool IsFilled;
        void Order(products)
        {
            Products = products;
            IsFilled = false;
        }
        void Fill()
        {
            IsFilled = true;
            //TODO: obviously - more stuff needed here
        }
        Money TotalPrice()
        {
            return Products.Sum(x => x.Price);
        }
    }
    
    class System
    {
        void Main()
        {
            SimulateCustomerPlacingAnOrder();
            SimulateFulfillmentPeople();
        }
        void SimulateCustomerPlacingAnOrder()
        {
            customer = new Customer();
            customer.Cart.AddProduct(allProducts.First());
            allCustomers.Add(customer);
        }
        void SimulateFulfillmentPeople()
        {
            foreach (var customer in allCustomers)
            {
                foreach (var order in customer.UnfulfilledOrders())
                    order.Fill();
            }
        }
    }
    

    一开始 - 这似乎是一个巨大的矫枉过正。使用过程代码 - 只需很少的集合和很少的 for 循环就可以实现相同的目标。但是领域驱动设计的想法是解决真正复杂的问题。

    面向对象的编程非常适合 - 有了它,您可以抽象出在您前进时无关紧要的事情。此外 - 重要的是相应地命名事物,这样您(和您的领域专家(理解问题的人))即使在多年后也能够理解代码。不仅是代码,还可以用一种无处不在的语言进行交流。

    请注意,我不知道电子商务领域以及您可能试图解决什么样的问题,因此 - 我很可能只是根据您的心理模型写了完全废话。这就是为什么教授领域建模如此混乱和困难的原因之一。另外 - 它需要高超的抽象思维能力,据我了解,这不是获得 CS 学位的主要要求。


    您对有界上下文很有意见。但是您应该记住,它们增加了它们之间的翻译需求。它们增加了复杂性,并且像往常一样 - 复杂的解决方案仅适用于复杂的问题(ddd 本身也是如此)。所以 - 只要您的域实体的含义不重叠,您就应该避免向它们发送垃圾邮件。第二个原因(不太“自然”)是强烈需要分解。

    附:阅读Evans book。两次...直到有意义... :)

    【讨论】:

    • 在阅读了 Vaughn Vernon 的 IDDD 之后,我的印象是您的示例未能正确地模拟事情应该如何。 OrderProduct 甚至 Customer 在购物环境和运输环境中都有非常不同的方式。例如,订单的Fill 操作在购物环境中毫无意义。虽然我觉得这个例子在战略上不正确,但我不确定如何从战术上解决这个问题。
    • @plalx 可能。正如我所写 - 我会在此处开始。另一件事-英语不是我的母语。也 - 我很久以前写过这个。但是,是的-您的方向正确。意义和命名很重要。 ddd 几乎是关于您如何准确地理解和反映业务逻辑。
    【解决方案2】:

    我认为你的观点是正确的。上下文处理同一现实世界概念的不同方面。在您的情况下,您可能将订单表示为用户的某种购物车抽象,同时以某种与使用的 ERP 兼容的形式。

    DDD 的上下文基本上说可以使用两个完全不同的模型(在不同的上下文中)来表示某个概念,并在需要时提供这些模型之间的显式映射,而不是试图将订单的概念硬塞进一个模型中。这可以防止模型聚合通常在尝试在多种上下文中使用相同模型时潜入的杂物。

    【讨论】:

    • 有界上下文是一种普遍存在的语言一致的地方。
    【解决方案3】:

    如果您对 java 中的示例没问题,这可能很有用:http://dddsample.sourceforge.net/

    【讨论】:

    • 此示例不显示多个有界上下文。它实际上是一个具有多个聚合的。我知道是因为我使用了这个示例(用于 .net 的示例),并且毫无疑问,这是一个很好的学习示例,但根本没有多个有界上下文。这就是我在这里浏览文章的原因。
    猜你喜欢
    • 2015-04-23
    • 1970-01-01
    • 2012-10-16
    • 2014-07-07
    • 2013-11-27
    • 2021-02-23
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多