0

假设您有一个贫血的域模型 (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" });
    }
}

后来,在其他地方,你有这个代码:

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

现在,除了领域模型之外,还有一个称为的方面DomainValidationAspect,它在新员工将要在实现中持久化之前对其进行验证Repository

整体ValidateEmployeeAspect可以在添加或更新时验证一个Employee,这是添加角色的情况。它负责加载Employee的域规则并对其进行验证。域规则是使用规范模式实现的。

最后,一切都发生在域事务中。

是的,从面向对象编程的角度来看,它似乎是一个贫乏的领域模型,但面向方面的编程呢?

所以问题是...

...可能只是因为

  • ...在这种情况下,Employee使用集合接口添加角色?
  • Employee...从纯面向对象编程的角度来看,没有行为?

一些单词

我的观点是,面向方面的编程确实存在在领域(或任何其他层)的主要流程中隐藏大量细节的缺点,但是对面向对象和面向方面背后的概念进行了鸟瞰方法将映射到丰富的域模型而不是贫乏的域模型

4

2 回答 2

3

想到几点(排名不分先后):

  • 在域驱动设计中,永远不允许聚合(这里是Employee处于无效状态。它自己强制执行其不变量,因此不需要外部验证。

  • 这对我来说听起来很像 CRUD。为什么要在简单的CRUD上强制DDD

  • EmployeeManager除了包装存储库方法并因此只是另一层复杂性之外,还能做什么。

  • ArepositoryOfEmployeesInstance对我来说听起来很不自然。就像您不会调用类一样,EmployeeClass或者EmployeeManagerClass为什么要在对象后缀Instance?

    另外为什么要附加模式名称(这里是Repository)?继续打电话吧employees。这听起来很真实:

    employees.GetByName(name)

    甚至更好: employees.Called(name)

于 2013-01-11T10:58:14.287 回答
1

我的观点是,面向方面的编程确实存在在领域(或任何其他层)的主要流程中隐藏大量细节的缺点

IMO,这是在 DDD 中使用此类 AOP 方法的核心问题——它隐藏了细节。现在,对于严格的技术领域,例如日志记录,这通常是可取的。AOP 适用于此类领域,因为从某种意义上说,它是技术领域本身的一个特征——传统 OOP 组合的扩展。另一方面,DDD 针对非技术领域——业务用例。因此,DDD 的目标之一是领域知识的提炼尽可能将其从技术问题中解放出来。实现 OOP 的一个步骤是将数据和行为聚集在对象内部。另一个步骤是从行为的技术名称转向行为的更多业务特定名称。这使您可以捕获与行为相关的周围业务上下文,而不仅仅是技术上下文。

对 DDD 有帮助的是一组新的抽象。不是不必要的复杂层,而是创造新语义的东西。正如Dijkstra所说,抽象应该创建新的语义级别。这可以以 DSL 的形式出现,允许表达与技术问题无关的领域知识。然后,应用程序会将这个 DSL 表示的域附加到基础设施——持久性、UI、服务等。创建这样的 DSL 既具有表现力又易于“附加”是一个巨大的挑战。

要回答您的问题,是的,您的对象模型本身就是贫血的,即使它通过方面由更丰富的行为组成。但是,这仅针对您的对象模型,并且对象模型是否贫血只是难题的一部分-对象模型是一种战术模式而不是战略模式。

您的目标似乎朝着正确的方向前进——您希望提升抽象级别,使其超出 OOP 单独提供的设施。我只是认为 AOP 的缺点超过了 DDD 案例中的好处。

于 2013-01-11T17:35:02.443 回答