Domain driven design DDD-有界上下文和多个模型?

Domain driven design DDD-有界上下文和多个模型?,domain-driven-design,bc,Domain Driven Design,Bc,我正在阅读DDD中有界上下文的概念,我开始意识到我对模型在实践中的确切外观并没有清晰的理解。(我甚至可能不知道域名的确切含义。) 让我们看看流行的电子商务示例:客户浏览产品,添加到购物车,下订单。订单执行人员发送订单 是否存在一个具有多个有界上下文(产品目录上下文、购物车上下文、订单上下文、履行上下文)的大型电子商务域?每个有界上下文是否包含一组模型(因此产品目录上下文包含产品、产品图像和产品评论的模型) 离我还有多远?如果您对java中的示例没有异议,这可能会很有用:我认为您的观点是正确的。上

我正在阅读DDD中有界上下文的概念,我开始意识到我对模型在实践中的确切外观并没有清晰的理解。(我甚至可能不知道域名的确切含义。)

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

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


离我还有多远?

如果您对java中的示例没有异议,这可能会很有用:

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


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

至少你的思路是正确的。典型的错误是只看到模式

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

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

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

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本身也是如此)。所以,只要域实体的含义不重叠,就应该避免垃圾邮件。第二个原因(不太“自然”)是强烈的分解需求


附言:读。两次。。。直到它有意义……:)

此示例不显示多个有界上下文。它实际上是一个具有多个聚合的集合。我知道这一点,因为我使用了这个示例(用于.net的示例),而且,这是一个值得学习的好示例,但根本不是多个有界上下文。这就是我在这里浏览文章的原因。有限的上下文是一种普遍存在的语言保持一致的地方。在阅读了沃恩·弗农的IDDD之后,我的印象是,您的示例未能正确地模拟事物应该是怎样的。一份
订单
一份
产品
甚至一位
客户
在购物环境和运输环境中都有非常不同的方式。例如,订单的
Fill
操作在购物环境中毫无意义。虽然我觉得这个例子在战略上不正确,但我不确定如何从战术上解决这个问题。正如我所写,我将从这里开始。另外,英语不是我的母语。还有,我很久以前写过这篇文章。但是是的,你的方向是对的。意义和命名非常重要。ddd主要是关于您理解和反映业务逻辑的准确程度。