Question

I'm new to Domain Driven Design and trying to figure out what should put where. Assume I have a class called Order and a related DTO called OrderDto.

The front end calls the OrderController (MVC architecture) by passing the OrderDto and the controller calls the OrderService.

Then I use OrderRepository to get the Order from the database and update the Order using OrderDto. Assume I want to calculate Total, VAT and Subtotal every time, a customer Add/ Edit orders. The Question is, in the DDD where should I put these calculations.

  1. In the service layer as private methods such as RecalculateTotal or in a helper class as a Static method
  2. Inside the behaviour class
  3. Inside the Domain (Class member setters)

At the moment I do it in the service layer but I'm certain I have missed something. Because every time a user add or remove product from his order I have to call my recalculation methods manually. I think this calculation should be done automatically. So I don't have/ need to worry about these calculation.

Any help would be much appreciated.

Update 1
in summery where we should put our business rules in DDD?

Was it helpful?

Solution

"If the rule exists because the business requires it, then it belongs in the Domain"

In the spirit of DDD, put all your calculations in your Domain.

There is a reason why the Domain is sometimes called "Business Layer", because it contains all related business logic/rules.

The following code is an example of a pure DDD. Total calculations are done automatically every time you add an order, you don't need to worry about forgetting to explicitly call a "calculate routine".

public class Order
{
    public void AddItem(Item item)
    {
        // Do add item here
        this.CalculateTotal(); // At the end, calculate total.
    }

    private void CalculateTotal()
    {
        // Do calculations
        this.Total = 0; // after calculations, assign new value;
    }

    public decimal Total { get; private set; } // notice the "private" setter?
}

You don't have to worry about calculations, freeing your mind to focus on other things.

And if you need to change the calculations, all you need to do is go to the one place where the business logic is contained. Welcome to Domain Driven Design ^_^

UPDATE

The following is an updated code in response to the comment with regards to the VAT.

VAT

Again, the calculation of with VAT is done automatically inside the CalculateTotal()

If the VAT depends per country, then simply create a Country with VAT property. Put country property on Customer, as follows:

public class Customer
{
    public Country Country { get; set; }
}

public class Country
{
    public string Name { get; set; } // Country Name
    public decimal Vat { get; set; }
}

In the CalculateTotal(), simply check the customer if they are affected by VAT depending on their country.

public class Order
{
    public void AddItem(Item item)
    {
        // Do add item here
        this.CalculateTotal(); // At the end, calculate total.
    }

    private void CalculateTotal()
    {
        // Do calculations

        // Get Vat
        decimal vat = this.Customer.Country.Vat;
        this.Total = 0; // after calculations, assign new value;
    }

    public Customer Customer { get; set; }
    public decimal Total { get; private set; } // notice the "private" setter?
}

If you plan to change the VAT, then you know where to look (The Country ofcourse)

Any changes to the VAT will affect all customers within that country.

OTHER TIPS

I prefer to create a OrderCaluclate Interface and required methods like "calculateTotal", "calculateVAT", etc... Then I create the different order Calculate and by using the Strategy design pattern I create the relation between Order and OrderCalculate.

By doing this way, you give flexibility of Order calculation as well, like some additional parameters required for certain Order calculation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top