domain-driven-design - 贫血域模型或 "where to put logic"

标签 domain-driven-design business-logic

这是“分析瘫痪”似乎已经站稳脚跟的场景之一,所以请指教!

项目

一个相当简单的汽车产品列表,其中包括零件引用、适合的车辆等详细信息。

前端是一个 asp.net MVC 应用程序。

后端是 SQL,使用 Subsonic 将产品投影到域对象中。

功能

我们的屏幕之一是产品详细信息屏幕。 ASP.NET MVC Controller 调用产品存储库来检索产品详细信息,将这些详细信息(通过一些自动映射到 viewModel)返回到 View 。

现在的杀手锏是我们有两个或三个 channel 进入网站,根据 channel 的不同,用户需要看到不同的零件编号。

例如,如果是零售 channel ,则零件编号与数据库中的零件编号相同,但如果用户通过贸易 channel 访问该站点,则零件引用的开头将替换为替代编号。

例如如果通过交易 channel 查看,0900876 将变为 1700876。

我正在努力的地方是决定在哪里封装关于部件引用(以及其他可能改变的细节)的“ channel 规则”。

我已经考虑过这些替代方案。

将逻辑直接写入域对象

产品 类我们可以有一个方法/属性来获取翻译的部分引用。

public string TranslatedPartRef()
    {
        if (this.Channel == "Trade")
        {
            return PartRef.Replace("0900", "1700");
        }
        else
        {
            return PartRef;
        }
    }      

在这种情况下,Product 实例必须知道 channel ,这对我来说似乎是错误的。

将逻辑封装在另一个对象中

我们可以编写一个类来处理这部分引用翻译,或者创建一个 channel 包含此逻辑的类。

我不明白的是如何协调这两个类(class)。

如果 Controller 调用存储库来检索产品,那么它是否应该确定使用了哪个 channel 并翻译部件引用?如果是这样,我如何将带有翻译部分引用的产品发送回 View ?

还值得注意的是,这部分引用也必须出现在搜索结果和其他场景中,因此我认为它需要整齐地包含在某个域中。

最佳答案

我不是 C# 人,但我想我会用 Java 中的装饰器来解决这个问题。

假设您有一个产品接口(interface),那么您可以创建一个装饰器来管理部件号问题。

class Product implements IProduct {
    public String getProductCode();
    // etc
}

class ProductChannelDecorator implements IProduct
{
    // constructor, like this in C#?
    public ProductChannelDecorator(IProduct product, Channel channel) { 
        this.product = product;
        this.channel = channel;
    }
    public String getProductCode() {
        switch (this.channel) {
            case Channel.RETAIL:
                return this.decorated.getProductCode();
            case Channel.TRADE:
                return retailToTradeTransformer(this.product.getProductCode());
            // etc
        }
    }
    // etc
}

关于domain-driven-design - 贫血域模型或 "where to put logic",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1425749/

相关文章:

domain-driven-design - 如何在领域驱动设计中处理跨域逻辑

java - 如何准确定义域服务

domain-driven-design - 正确设计汇总根

c# - 哪一层做类似: caching and logging belong?的功能

c# - 业务对象和数据访问对象之间的存储库模式和映射

documentation - 了解新项目中业务逻辑的最快方法

rest - 通过 REST 和消息队列使用微服务和多输入的 DDD

java - 领域驱动设计中的 JPA 实体责任

java - 设计 : When the line between domain objects and service objects isn't clear

java - Java Spring Boot如何实现Business Logic层和Repository层?