I have a question about DDD. I'm building a application to learn DDD and I have a question about layering. I have an application that works like this:
UI layer calls => Application Layer -> Domain Layer -> Database
Here is a small example of how the code looks:
//****************UI LAYER************************
//Uses Ioc to get the service from the factory.
//This factory would be in the MyApp.Infrastructure.dll
IImplementationFactory factory = new ImplementationFactory();
//Interface and implementation for Shopping Cart service would be in MyApp.ApplicationLayer.dll
IShoppingCartService service = factory.GetImplementationFactory<IShoppingCartService>();
//This is the UI layer,
//Calling into Application Layer
//to get the shopping cart for a user.
//Interface for IShoppingCart would be in MyApp.ApplicationLayer.dll
//and implementation for IShoppingCart would be in MyApp.Model.
IShoppingCart shoppingCart = service.GetShoppingCartByUserName(userName);
//Show shopping cart information.
//For example, items bought, price, taxes..etc
...
//Pressed Purchase button, so even for when
//button is pressed.
//Uses Ioc to get the service from the factory again.
IImplementationFactory factory = new ImplementationFactory();
IShoppingCartService service = factory.GetImplementationFactory<IShoppingCartService>();
service.Purchase(shoppingCart);
//**********************Application Layer**********************
public class ShoppingCartService : IShoppingCartService
{
public IShoppingCart GetShoppingCartByUserName(string userName)
{
//Uses Ioc to get the service from the factory.
//This factory would be in the MyApp.Infrastructure.dll
IImplementationFactory factory = new ImplementationFactory();
//Interface for repository would be in MyApp.Infrastructure.dll
//but implementation would by in MyApp.Model.dll
IShoppingCartRepository repository = factory.GetImplementationFactory<IShoppingCartRepository>();
IShoppingCart shoppingCart = repository.GetShoppingCartByUserName(username);
//Do shopping cart logic like calculating taxes and stuff
//I would put these in services but not sure?
...
return shoppingCart;
}
public void Purchase(IShoppingCart shoppingCart)
{
//Do Purchase logic and calling out to repository
...
}
}
I've seem to put most of my business rules in services rather than the models and I'm not sure if this is correct? Also, i'm not completely sure if I have the laying correct? Do I have the right pieces in the correct place? Also should my models leave my domain model? In general I'm I doing this correct according DDD?
Thanks!
Domain-Driven Design(DDD) is a collection of principles and patterns that help developers craft elegant object systems. Properly applied it can lead to software abstractions called domain models. These models encapsulate complex business logic, closing the gap between business reality and code.
Domain Layer It is the layer where all business rules related to the problem to be solved are included. In this layer; entities, value objects, aggregates, factories and interfaces will take place. This layer should be kept away from dependencies as much as possible.
Domain-driven design is the idea of solving problems of the organization through code. The business goal is important to the business users, with a clear interface and functions. This way, the microservice can run independently from other microservices.
The domain layer is an optional layer that sits between the UI layer and the data layer. Figure 1. The domain layer's role in app architecture. The domain layer is responsible for encapsulating complex business logic, or simple business logic that is reused by multiple ViewModels.
When you ask
Should my models leave my domain model?
I would say that if at all possible you should work to avoid shuffling data back and forth between different sets of objects in one program. Doing that would result in you going through a lot of tedium writing a lot of boring and error-prone code, you will have a redundant set of DTO objects that have to mirror your domain objects, also you get less mileage out of the methods you write because they only operate on either the DTOs or domain objects. All in all it is very painful and doesn't accomplish much. I try to have one set of domain objects that is passed around throughout the application.
(That doesn't mean there aren't cases where you really have a need to move data between different sets of objects, like when building an anti-corruption layer. Just don't go looking for trouble if it's not absolutely necessary.)
As for
IShoppingCart shoppingCart = repository.GetShoppingCartByUserName(username);
//Do shopping cart logic like calculating taxes and stuff
//I would put these in services but not sure?
one of the goals of Domain-Driven Design is to try to separate business logic from infrastructure code. Whatever you can figure out how to calculate using only the domain objects is better off going into the domain model, where you can write tests for it that do not involve the database. I would want to have the service pull an aggregate of domain objects, then have the business logic calculations happen in the domain objects, then have the service save the state changes that the calculations brought about in the domain objects.
DDD works best when services (application layer) expose only commands on domain objects, not the objects themselves.
In you example I would create a service method like Purchase(strng productName, int quantity) which internally would get a ShoppingCart from Repository (don't have to use interface here) get a Product (by its name) from Repository and call cart.AddProduct(product, quantity)
not, the business logic of adding products to cart, calculating total amount, total weight or other business stuff is encapsulated in the mode.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With