Domain driven design DDD和获取域类中的附加信息

Domain driven design DDD和获取域类中的附加信息,domain-driven-design,ddd-repositories,Domain Driven Design,Ddd Repositories,我想我已经阅读了16154条关于DDD和最佳实践的问题、博客帖子、推文等。为另一个类似的问题道歉。假设我的数据库中有三个表:User、Department和UserDepartment。一切都很简单。我需要建立一个层次结构,显示用户可以访问哪些部门。问题是,我还需要向他们展示他们可以访问的上级部门 最好在我的用户类上使用GetDepartments()方法吗?现在我有一个带有GetDepartments(字符串用户名)的用户服务,但我觉得这不是最佳解决方案。如果首选user.GetDepartm

我想我已经阅读了16154条关于DDD和最佳实践的问题、博客帖子、推文等。为另一个类似的问题道歉。假设我的数据库中有三个表:User、Department和UserDepartment。一切都很简单。我需要建立一个层次结构,显示用户可以访问哪些部门。问题是,我还需要向他们展示他们可以访问的上级部门

最好在我的用户类上使用GetDepartments()方法吗?现在我有一个带有GetDepartments(字符串用户名)的用户服务,但我觉得这不是最佳解决方案。如果首选user.GetDepartments(),那么如何访问存储库以获取用户有权访问的父部门

我不认为这很重要,但我使用的是实体框架

public class User
{
    [Key]
    public int UserId { get; private set; }

    [Display(Name = "User Name")]
    public string UserName { get; private set; }

    [Display(Name = "Email")]
    public string Email { get; private set; }

    [Display(Name = "UserDepartments")]
    public virtual ICollection<UserDepartment> UserDepartments { get; private set; }

    public List<Department> GetDepartments()
    {
        // Should this be here? and if so, what's the preferred method for accessing the repository?
    }
}
公共类用户
{
[关键]
public int UserId{get;private set;}
[显示(Name=“User Name”)]
公共字符串用户名{get;private set;}
[显示(Name=“电子邮件”)]
公共字符串电子邮件{get;private set;}
[显示(Name=“UserDepartments”)]
公共虚拟ICollection用户部门{get;private set;}
公共部门名单(
{
//应该在这里吗?如果是,访问存储库的首选方法是什么?
}
}
DDD更多的是关于行为,这也意味着它是面向TDA(告诉,不要问)的

通常,您以一种告诉他们该做什么而不是询问信息的方式来构建聚合

更重要的是,如果聚合需要一些额外的信息来执行其行为,那么他们的工作通常不是找出从何处获取这些信息

现在,当您说您的用户聚合具有GetDepartments方法时,它引起了一个警钟。聚合是否需要这些信息来执行任何类型的行为?我不这么认为,只是你想显示一些数据

所以我在这里看到的是,您试图根据数据表而不是行为来构造聚合。 这实际上是应用DDD时的#2错误(#1没有考虑有界上下文)

同样,聚合表示系统的业务逻辑和行为。这意味着您不必从聚合中读取。你的阅读端可以做得容易得多——只需对数据库进行一次该死的查询

但是,一旦您需要要求您的系统做一些事情,现在您可以通过聚合来完成:AppService将从存储库中加载一个,并调用其行为方法

这就是为什么通常在聚合中没有属性,只有表示行为的方法

另外,无论如何,您也不希望将聚合映射到数据表,这不是它们的工作,而是存储库的工作。实际上,您不希望域依赖于任何东西,尤其是基础设施

如果你想去DDD方向,那么考虑以下内容:

  • 构造聚合以封装行为,而不是表示数据表
  • 不要让您的域依赖于基础设施等
  • 使存储库负责加载/保存聚合。聚合本身应该对持久性、数据结构等一无所知
  • 您不必通过聚合读取数据 把#4想象成您的系统有两个方面:当您只是读取数据并在UI中显示它们时的“读取”方面,以及当您执行操作时的“命令”方面

    第一个(read)非常简单:愚蠢的查询以您想要的方式读取数据。它不会影响任何东西,因为它只是阅读,没有副作用

    第二个是当你在你的领域中进行更改时


    再次强调,记住DDD的第一条规则:如果您没有业务逻辑和行为模型,那么就不要进行DDD。

    谢谢。这很有帮助。我认为#4一直是我最大的绊脚石,而#1也在组合中。到目前为止,我一直避免让我的域名知道任何其他事情,但我一直在这个问题上挂断电话。你的澄清帮助很大。衷心感谢。