3

Say I have an MVP app. The form has four textboxes:

  1. Quantity
  2. Price
  3. Product
  4. TotalPrice

The app calls a web service and then recommends products that may be cheaper based on the quantities being bought.

Is it acceptable to set the total price on the client using a setter, i.e.

TotalPrice = Quantity*Price 

or should the total price be set in the domain layer and then returned to the client? It would be simple to do something like this on the client:

public decimal TotalPrice
        {
            get
            {
                return Price*Quantity;
            }
        }

Then in the Presenter do something like this:

if (View.TotalPrice>0)
{
//call domain layer
}

Is it acceptable to do calculations like this in the View/Presenter before calling a web service or is this considered domain level validation?

Please note that I am talking specifically from a best practice perspective.

3
  • when I use to do MVP, we did minor validations in the presenter to be able to help guide the information along the way. Views though definitely not meant to do any logic as they simply hold data presented.
    – ggiaquin16
    Commented Jun 7, 2017 at 17:54
  • @ggiaquin, thanks. What about doing if statements in the Presenter (see my question). Is that "bad"?
    – w0051977
    Commented Jun 7, 2017 at 18:40
  • A related question
    – radarbob
    Commented Jun 7, 2017 at 23:44

4 Answers 4

4

"Best practice" is usually short hand for "whatever matches my prejudices". It's not an objective evaluation, and specific cases may require a departure from best practice...

So, here are my prejudices.

Firstly - work with whatever your framework is, and use the accepted style of development. This makes it easier to understand the application, and that's usually the biggest contribution to "best practice".

The second recommendation is "don't repeat yourself" (also known as DRY). Work out which bit of logic is responsible for calculating total price, and don't let other code repeat it.

The whole point of MVP/MVC frameworks is that domain logic lives in the controller; this is a reaction to unstructured applications which were hard to maintain because the domain logic got spread all over the architecture, and made it hard to debug, test and understand.

In your case, imagine your "total price" evolves over time to include tax calculations. And shipping costs. And discounts based on volume pricing. Also imagine you want to write automated unit tests to verify your total price calculation is correct. That's really hard to do if that one bit of logic is hidden in the controller/presenter layers.

All this is a reason to put the price calculation in the domain layer, and call it from the front-end as and when you need it.

There are exceptions to this rule - usually driven by performance and responsiveness considerations. If you want to provide rapid feedback to the user when they enter values in a form, the server roundtrip may be too slow, so it may make sense to duplicate some logic on the client. This is often the case with form validation logic. However - this introduces duplication, which is a maintenance burden - so only do it if you know you have a performance problem, and cannot solve it in any other way.

3

It is preferable to do this calculation in the domain model. Developers often overlook plural business entities... ProductCollection.TotalPrice

With that said, I don't think it's bad to do a simple collection calculation like this in the controller or presenter. Just make sure you move it later if aggregate calculations become more complex or numerous.

However, to me, putting it in the view is completely unacceptable. Views should not contain any logic, their only job is to define the layout of what the user sees.

2
  • Thanks. What about doing if statements in the Presenter (see my question). Is that "bad"? Thanks again.
    – w0051977
    Commented Jun 7, 2017 at 18:39
  • 1
    Not preferable, again belongs in the the business model. However, I would not see it as a problem either. Commented Jun 7, 2017 at 18:45
2

In cases like this I duplicate some of the logic on the client side, only as an optimization and only when otherwise would affect badly the user experience. The idea is that DDD must not affect the user experience in such a way that is bad for business.

However, the final calculation is done once again in the Domain layer, before persisting changes of an Aggregate.

There is a risk that, when the business logic is changing, the client side code (the presentation layer in this case) is missaligned with the Domain layer code but you, as a developer, should know if it is acceptable.

0

Yes its a bad practice to do calculations in controller layer. Controller layer is only meant for delegation of request to service layer . Service layer should take care of any calculations we have .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.