首页
学习
活动
专区
圈层
工具
发布

域建模
EN

Software Engineering用户
提问于 2018-04-14 08:27:42
回答 1查看 121关注 0票数 3

我正在研究一个应用程序的域模型,该应用程序存储由卖家提供的关于他们在平台上销售的商品的信息。应用程序只是充当此信息的数据存储。这些信息被称为"ProductFact",可能是多种多样的。下面的每个示例表示一个"ProductFact“实例。

  1. 该商品面向公众的销售价格。
  2. 卖方可以为某些特定客户提供的折扣(绝对金额,或销售价格的百分比)。
  3. 客户为获得免费运输而必须购买的最低数量。

以上是目前已知的一些案例,但未来可能会有更多的案例出现,无法保证与已经存在的"ProductFact"s共享任何财产。不同的客户将调用这个应用程序,每个客户都在寻找一种特定类型的"ProductFact“。

我们将使用NoSQL后端,所以db模式不是问题。问题在于应用层。我不知道如何模拟这个特定的物体。我一直试图把它建模为:

代码语言:javascript
复制
public class ProductFact {
    private ProductFactType productFactType; //enum for different types like SELLING_PRICE, DISCOUNTS, MIN_QUANT, etc.
    private ProductFactData productFactData; // for representing the actual data.
}

如果ProductFactData有一个行为的话,这将是非常理想的,所以我可以使用它作为一个接口,并创建实现或每个用例。但这只是数据,继承似乎是一种讨厌的方法。

另一种办法可以是:

代码语言:javascript
复制
public class ProductFact {
    private ProductFactType productFactType;

    private SellingPriceFactData sellingPriceFactData;
    private DiscountFactData discountFactData;
    .
    .
    .
    private SomeProductFactData someProductFactData;
}

客户机可以检查"productFactType“的值,然后为适当的FactData type.But调用getter,即使这种方法看起来很麻烦。

怎样才能更好地模拟这种情况呢?

编辑

问题陈述似乎需要一些更清晰的说明。折扣和价格是应用程序可以存储的许多"ProductFact"s中的两个。今后可能还会有其他情况,包括:

  1. 有关该产品的快递资格的信息,如"ExpressDeliveryProductFact“--该产品可用于哪些领域,要求的最低数量是多少。
  2. 关于产品状况的信息-它是用的,新的吗?

会有不同的客户端来查询这个应用程序,每个客户端都在寻找它感兴趣的ProductFact类型。例如,DeliveryService客户端会对"ExperssDeliveryProductFact“感兴趣。

可以看到,这些信息似乎没有任何共同之处,这在领域模型中提出了问题。

EN

回答 1

Software Engineering用户

发布于 2018-04-15 07:36:47

要正确地以面向对象的方式建模,请将思维转变为面向对象的设计模式。

例如,您可以应用策略模式对每种情况下的产品价格应用折扣。

在模型中为折扣策略定义一个接口:

代码语言:javascript
复制
public interface iDiscountStrategy
{
     decimal ApplyExtraDiscountTo(decimal originalSalePrice);
}

添加每种类型的折扣作为折扣策略的实施。下面是百分比折扣和无折扣实现(在您的模型中也定义它们):

代码语言:javascript
复制
public class TradeDiscountDiscountStrategy : IDiscountStrategy
{
    public decimal ApplyExtraDiscountTo(decimal originalSalePrice)
    {
        decimal price = originalSalePrice;
        price = price * 0.95M;
        return price;
    }
}

public class NullDiscountStrategy : IDiscountStrategy
{
    public decimal ApplyExtraDiscountTo(decimal originalSalePrice)
    {
        return originalSalePrice;
    }
}

你的Price模型实体。它使用DI的设置风格使折扣策略能够应用于产品的价格:

代码语言:javascript
复制
public class Price
{
    private IDiscountStrategy discountStrategy = new NullDiscountStrategy();

    private decimal sellingPrice;

    public Price(decimal sellingPrice)
    {
        this.sellingPrice = sellingPrice;
    }

    public void SetDiscountStrategyTo(IDiscountStrategy discountStrategy)
    {
        this.discountStrategy = discountStrategy;
    }

    public decimal SellingPrice
    {
        get
        {
            return this.discountStrategy.ApplyExtraDiscountsTo(this.sellingPrice);
        }
    }
}

请注意,Price可能包含任何其他逻辑(即“行为”),如储蓄计算等。

ProductFact变成:

代码语言:javascript
复制
public class ProductFact
{
    public Price Price { get; set; }
    // ...
}

要应用每个客户类型的折扣,您需要创建以下枚举:

代码语言:javascript
复制
public enum CustomerType
{
    Standard = 0,
    Trade = 1
}

您还需要创建一个工厂类,其唯一责任是返回给定CustomerType的匹配折扣策略:

代码语言:javascript
复制
public static class DiscountFactory
{
    public static IDiscountStrategy GetDiscountStrategyFor(CustomerType customerType)
    {
        switch (customerType)
        {
            case CustomerType.Trade:
                return new TradeDiscountStrategy();
            default:
                return new NullDiscountStrategy();
        }
    }
}

就是这样。然后,在您的服务层中,您可以编写如下内容:

代码语言:javascript
复制
public class ProductFactService
{
    public IList<ProductFact> GetAllProducts(CustomerType customerType)
    {
        IDiscountStrategy discountStrategy = DiscountFactory.GetDiscountStrategyFor(customerType);

        IList<ProductFact> products = // get products from database

        foreach (ProductFact pf in products)
        {
            pf.Price.SetDiscountStrategyTo(discountStrategy);
        }

        retur products;
    }
}

对于你领域的其他部分,有同样的思维方式,你的建模问题就会消失。

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

https://softwareengineering.stackexchange.com/questions/369356

复制
相关文章

相似问题

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