I've read some of the questions regarding anemic domain models and separation of concerns. What are the best techniques for performing/attaching domain logic on anemic domain objects? At my job, we have a pretty anemic model, and we're currently using "helper" classes to perform the database/business logic on the domain objects. For example:
public class Customer
{
public string Name {get;set;}
public string Address {get;set;}
}
public class Product
{
public string Name {get;set;}
public decimal Price {get;set;}
}
public class StoreHelper
{
public void PurchaseProduct(Customer c, Product p)
{
// Lookup Customer and Product in db
// Create records for purchase
// etc.
}
}
When the app needs to do a purchase, it would create the StoreHelper, and call the method on the domain objects. To me, it would make sense for the Customer/Product to know how to save itself to a repository, but you probably wouldn't want Save() methods on the domain objects. It would also make sense for a method like Customer.Purchase(Product), but that is putting domain logic on the entity.
Here are some techniques I've come across, not sure which are good/bad:
- Customer and Product inherit from an "Entity" class, which provides the basic CRUD operations in a generic fashion (using an ORM maybe).
- Pros: Each data object would automatically get the CRUD operations, but are then tied to the database/ORM
- Cons: This does not solve the problem of business operations on the objects, and also ties all domain objects to a base Entity that might not be appropriate
- Use helper classes to handle the CRUD operations and business logic
- Does it make sense to have DAOs for the "pure database" operations, and separate business helpers for the more business-specific operations?
- Is it better to use non-static or static helper classes for this?
- Pros: domain objects are not tied to any database/business logic (completely anemic)
- Cons: not very OO, not very natural to use helpers in application code (looks like C code)
- Use the Double Dispatch technique where the entity has methods to save to an arbitrary repository
- Pros: better separation of concerns
- Cons: entities have some extra logic attached (although it's decoupled)
- In C# 3.0, you could use extension methods to attach the CRUD/business methods to a domain object without touching it
- Is this a valid approach? What are pros/cons?
- Other techniques?
What are the best techniques for handling this? I'm pretty new to DDD (I'm reading the Evans book - so maybe that will open my eyes)