tags:

views:

180

answers:

7

Ok, so I wanted to get opinions on this topic.

I have a dumb data object - CustomerOrder.

CustomerOrder has a price and a quantity but also has a TotalCash property (price * quantity). so I have a totalCash property but I dont want to put the calculation into the object directly because that would be breaking the dumb data object rule. I do need to get the cashflow over and over again throughout the app so I need to centralize the calculation. I could create a cashFlowCalculator class and pass in a customerOrder but I dont want another class for every simple calculation.

Any ideas or best practices?

A: 

I understand the rationale of keeping your data objects separate from your business logic. Using LINQ with designer generated classes, I feel comfortable extending the generated class with a partial class implementation that contains the business logic. I feel that this is enough separation for my needs. If this doesn't work for you then I would have both data objects and business objects -- perhaps with a 1-1 correspondence, perhaps not. A factory class or method can be used to translate between your business and data objects. Then simply implement your business logic in your business objects without need for auxiliary objects for your calculations.

tvanfosson
+1  A: 

In the same situation I would break the "dumb data object rule" since I don't expect that particular calculation to change often. I'd probably implement it as a getter.

For more complex scenarios, it makes sense to create an OrderCalculator class that takes in order-related classes and can perform all sorts of calculations such as included tax, measuring margins, etc. In this way you are delegating the responsibilities of performing a calculation outside of the CustomerOrder. That way the CustomerOrder does not need to know about the state tax in Texas to determine if sale tax is needed, for example.

DavGarcia
A: 

Why don't you adopt extension methods?

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

you could even move your extension static classes into different namespace.

lubos hasko
A: 

If this is a data transfer object (DTO) that is updated from a datatable, I would suggest adding a TotalCash Datacolumn to the table, and set the datacolumn Expression property to "price * quantity". Create a TotalCash readonly property in the dumb (DTO) class that get updated from the datatable. From a OO perspective that is the way it should be done.

Igor Zelaya
A: 

another option [probably too simple for the sophisticates 'round here ;-)] would be to let the dumb data object have properties for the calculated fields, but let the SQL query that retrieves the data do the calculation (once); make these fields read-only of course

Steven A. Lowe
A: 

I think you should consider if you really want TotalCash being a calculated/derived property...

Consider - if the business logic changes for the calculation, having the TotalCash property change retroactively for existing records may not be desirable.

I'd consider making property a non-calculated member of the DTO, and perhaps also use a TotalCostCalculation service class used to determine the set value.

just my 2 cents.

Ash Kim
A: 

I would do the calculation of TotalCash in your DTO (this would be YAGNI). If in the future you need to change the behavior of TotalCash, then maybe look at coming up with a TotalCashCalculator and pass this into the Order via DI.

Gutzofter