数据建模问题 - 数据和计算与访问逻辑的分离

时间:2009-01-15 03:51:02

标签: c# model-view-controller

好的,所以我想就这个话题得到意见。

我有一个愚蠢的数据对象 - CustomerOrder。

CustomerOrder有价格和数量,但也有TotalCash属性(价格*数量)。所以我有一个totalCash属性,但我不想直接将计算放入对象,因为这将破坏哑数据对象规则。我需要在整个应用程序中反复获取现金流量,因此我需要集中计算。我可以创建一个cashFlowCalculator类并传入一个customerOrder,但我不希望每个简单的计算都有另一个类。

任何想法或最佳做法?

7 个答案:

答案 0 :(得分:1)

在同样的情况下,我会破坏“哑数据对象规则”,因为我不希望特定的计算经常改变。我可能会把它当作一个吸气剂来实现。

对于更复杂的场景,创建一个OrderCalculator类是有意义的,该类接受与订单相关的类,并且可以执行各种计算,例如包含税,测量边距等。这样,您将委派执行的职责CustomerOrder之外的计算。这样,CustomerOrder就不需要知道德克萨斯州的州税,以确定是否需要销售税。

答案 1 :(得分:0)

我理解保持数据对象与业务逻辑分离的基本原理。使用LINQ和设计器生成的类,我觉得使用包含业务逻辑的部分类实现扩展生成的类很舒服。我认为这足以满足我的需求。如果这对你不起作用,那么我将拥有数据对象和业务对象 - 也许是1-1的对应关系,也许不是。工厂类或方法可用于在业务和数据对象之间进行转换。然后,只需在业务对象中实现业务逻辑,而无需计算辅助对象。

答案 2 :(得分:0)

为什么不采用扩展方法?

public sealed class CustomerOrder
{
    public decimal Price;
    public decimal Quantity;
}

public static class CustomerOrderExtensions
{
    public static decimal GetTotalCash(this CustomerOrder data)
    {
        return data.Price*data.Quantity;
    }
}

您甚至可以将扩展静态类移动到不同的名称空间中。

答案 3 :(得分:0)

如果这是从数据表更新的数据传输对象(DTO),我建议将TotalCash Datacolumn添加到表中,并将数据列Expression属性设置为“price * quantity”。在dumb(DTO)类中创建一个从数据表更新的TotalCash只读属性。从OO的角度来看,应该是这样做的。

答案 4 :(得分:0)

另一个选项[对于这里的老练人员来说可能太简单了;-)]会让哑数据对象具有计算字段的属性,但让检索数据的SQL查询进行计算(一次);这些字段当然是只读的

答案 5 :(得分:0)

我认为您应该考虑是否真的希望TotalCash是计算/派生属性......

考虑 - 如果计算的业务逻辑发生变化,那么可能不希望对现有记录追溯更改TotalCash属性

我会考虑将属性设为DTO的非计算成员,也可能使用用于确定设定值的TotalCostCalculation服务类。

只是我的2美分。

答案 6 :(得分:0)

我会在您的DTO中计算TotalCash(这将是YAGNI)。如果您将来需要更改TotalCash的行为,那么可以考虑使用TotalCashCalculator并通过DI将其传递给订单。