English 中文(简体)
数据建模问题 - 数据和计算及访问逻辑分离
原标题:
  • 时间:2009-01-15 03:51:02
  •  标签:

好的,我想要听一听大家对这个话题的意见。

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

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

任何想法或最佳实践?

最佳回答

在相同的情况下,我会违反“愚蠢的数据对象规则”,因为我不希望特定的计算经常发生变化。我可能会将其实现为一个getter。

对于更复杂的情况,创建一个OrderCalculator类是有意义的,它接收与订单相关的类,并可以执行各种计算,例如包括税收、测量利润等等。这样,您就将执行计算的责任委派给了CustomerOrder之外的部分。这样,例如,CustomerOrder不需要了解德克萨斯州的州税以确定是否需要销售税。

问题回答

我明白将数据对象与业务逻辑分开的理由。使用由设计程序生成的LINQ类时,我感到舒适并愿意使用一个包含业务逻辑的局部类实现来扩展生成的类。我觉得这已经足够分离我的需求了。如果这对你不起作用,那么我将有数据对象和业务对象——可能存在1-1的对应,也可能不存在。一个工厂类或方法可以用来在您的业务和数据对象之间进行转换。然后,只需在业务对象中实现您的业务逻辑,而不需要为计算使用辅助对象。

你为什么不采用扩展方法?

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;
    }
}

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

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

另一个选择(对于这里的大牛们来说可能过于简单)是让“愚蠢”的数据对象具有计算字段的属性,但是让检索数据的 SQL 查询进行计算(仅一次);当然要使这些字段为只读。

我认为你应该考虑一下,你是否真的想让TotalCash成为一个计算/派生属性...

考虑一下 - 如果计算的业务逻辑发生了变化,对于现有记录而言,让TotalCash属性的变化回溯可能并不理想

我会考虑使属性成为DTO中的非计算成员,并且可能还会使用TotalCostCalculation服务类来确定设置的值。

只是我的2分钱。

我会在你的DTO中计算TotalCash(这可能是YAGNI)。如果将来需要更改TotalCash的行为,那么可以考虑设计一个TotalCashCalculator并通过DI将其传递到Order中。





相关问题
热门标签