Domanda

Let's say you've an anemic domain model (ADM):

public class Employee
{
    public Employee() 
    {
        _roles = new List<Role>();
    }

    private IList<Role> _roles;

    public Guid Id { get; set; }
    public string Name { get; set; }

    public IList<Roles> Roles { get { return _roles; } }
}

public class EmployeeManager
{
    public Employee GetByName(string name) 
    {
        Contract.Requires(name != null);

        return repositoryOfEmployeesInstance.GetByName(name);
    }

    public void AddEmployee(string name) 
    {
        Contract.Requires(name != null);

        // The unique identifier will be generated by the OR/M behind the scenes...
        repositoryOfEmployeesInstance.Add(new Employee { Name = "Matias" });
    }
}

Later, in some other place, you've this code:

Employee some = new EmployeeManager().GetByName("Matias");
some.Roles.Add("Principal");

Now, in addition to the domain model, there's an aspect called DomainValidationAspect which validates the new employee just before it's going to be persisted in the Repository implementation.

The whole ValidateEmployeeAspect can validate an Employee either when one it's added or updated, which is the case of adding a role. It is responsible of loading Employee's domain rules and verifying them. Domain rules are implemented using the specification pattern.

Finally, everything happens in a domain transaction.

Right, it's seems to be an anemic domain model from the point of view of object-oriented programming, but what about aspect-oriented programming.

So the question is...

...may a domain-driven design be anemic just because:

  • ...in this case, Employee roles are added using the collection interface?
  • ...absence of behaviors in Employee from the point of view of pure object-oriented programming?

Some words

My opinion is it's true that aspect-oriented programming has the drawback of hiding a lot of details in the main flow of the domain (or any other layer), but a bird-eye on the concept behind an object-oriented plus aspect-oriented approach would map to a rich domain model rather than an anemic domain model.

È stato utile?

Soluzione 2

My opinion is it's true that aspect-oriented programming has the drawback of hiding a lot of details in the main flow of the domain (or any other layer)

IMO, this is the central problem of using such AOP approaches in DDD - it hides details. Now, for strictly technical domains, such as logging, this is often desirable. AOP works well for such domains because it is, in a sense, a characteristic of a technical domain itself - an extension to traditional OOP composition. DDD on the other hand targets non-technical domains - business use cases. As such, one of the goals of DDD is the distillation of domain knowledge freeing it from technical concerns as much as possible. A step toward achieving with OOP is clustering data and behavior together inside objects. Another step is moving away from technical names for behaviors to more business specific names for behaviors. This allows you to capture the surrounding business context associated with behaviors, not just the technical context.

What would be helpful for DDD is a new set of abstractions. Not a needless layer of complexity, but something that creates new semantics. As Dijkstra stated, abstractions should create new semantic levels. This can come in the form of a DSL that allows expression of domain knowledge agnostic of technical concerns. The application would then attach this DSL expressed domain to infrastructure - persistence, UI, services, etc. Creating such DSL that is both expressive and readily "attachable" is a big challenge.

To answer your question, yes your object model is itself anemic even though it is composed with richer behaviors through aspects. However, this only addresses your object model and whether an object model is anemic or not is only part of the puzzle - the object model is a tactical pattern not a strategic one.

Your goal seems to be headed in the right direction - you wish to elevate the level of abstraction beyond facilities provided by OOP alone. I just think that the drawbacks of AOP outweigh the benefits in the DDD case.

Altri suggerimenti

A few points come to mind (in no particular order):

  • In Domain-Driven Design an Aggregate (here an Employee) is never allowed to be in an invalid state. It enforces its invariants itself, so there should be no need for an external validation.

  • This sound very much like CRUD to me. Why force DDD upon simple CRUD?

  • What does EmployeeManager do except just wrapping the repository methods and therefore being only yet another layer of complexity.

  • A repositoryOfEmployeesInstance sounds very artificial to me. Just like you would not call a class EmployeeClass or EmployeeManagerClass, why would you suffix an object with Instance?

    Also why append the pattern name (here Repository)? Just go ahead and call it employees. That sounds like a real thing:

    employees.GetByName(name)

    Or even better: employees.Called(name)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top