代码之家  ›  专栏  ›  技术社区  ›  kitsune

您如何在考虑领域驱动设计的情况下为角色/关系建模?

  •  5
  • kitsune  · 技术社区  · 16 年前

    在数据库中,我目前有以下表格:Project、Person、ProjectRole Project\u Person with PersonId&ProjectId作为PK,ProjectRoleId作为FK关系。

    我在这里真的很困惑,因为我提出的所有领域模型似乎都违反了一些“DDD”规则。这个问题有什么“标准”吗?

    我看了一个流线型对象建模的例子,这里有一个项目和ProjectMember的样子,但Project中的AddProjectMember()会调用ProjectMember.AddProject()。所以Project有一个ProjectMember列表,作为回报,每个ProjectMember都有一个对项目的引用。我觉得有点复杂。

    使现代化

    在阅读了更多关于这个主题的内容后,我将尝试以下内容:有不同的角色,或者更好的是,模型关系,它们具有一定的重要性 角色类型 在我的领域内。例如,ProjectMember是一个独特的角色,它告诉我们一个人在项目中所扮演的关系。它包含一个ProjectMembershipType,它告诉我们有关它将扮演的角色的更多信息。我确实知道,人们必须在项目中扮演角色,所以我将对这种关系进行建模。

    一个人在一个项目中可以有许多角色,这些角色可以在某个日期开始和结束。此类关系由ProjectMember类建模。

    public class ProjectMember : IRole
    {
        public virtual int ProjectMemberId { get; set; }
        public virtual ProjectMembershipType ProjectMembershipType { get; set; }
    
        public virtual Person Person { get; set; }
        public virtual Project Project { get; set; }
        public virtual DateTime From { get; set; }
        public virtual DateTime Thru { get; set; }
        // etc...
    }
    

    public class ProjectMembershipType : IRoleType
    {
        public virtual int ProjectMembershipTypeId { get; set; }
        public virtual string Name { get; set; }
        public virtual string Description { get; set; }
    
        // etc...
    }
    
    5 回复  |  直到 16 年前
        1
  •  3
  •   Vijay Patel    16 年前

    以下是我将如何处理它:

    class Person
    {
      string Name { get; set; }
      IList<Role> Roles { get; private set; }
    }
    
    class Role
    {
      string Name { get; set; }
      string Description { get; set; }
      IList<Person> Members { get; private set; }
    }
    
    class Project
    {
      string Name { get; set; }
      string Description { get; set; }
      IList<ProjectMember> Members { get; private set; }
    }
    
    class ProjectMember
    {
      Project Project { get; private set; }
      Person Person { get; set; }
      Role Role { get; set; }
    }
    

    这个 项目成员

    请不要创建特定角色的课程-该课程已经学习。

    sample app 为了证明这一点(也包括关系):

    1. bin\debug\RolesRelationshipsSample.exe
    2. 拖放它们以指定适当的关系

    请随意使用代码。希望你觉得有用。

        2
  •  1
  •   tpdi    16 年前

    您正在对多对多关系进行建模:一个项目可以有许多人参与,一个人可以参与多个项目。

    您将关系建模为一个项目角色,该角色除了充当Person的双向链接之外<-&燃气轮机;项目中,还记录角色类型和该人员在该项目中填写该角色类型的开始/结束。(注意英文的“that”代表数据库FK,或者在代码中代表指针/引用?)

    select a.person_id, b.project_role_id, c.project_id
    from person a join project_role b on (a.id = b.person_id)
    join project c on (b.project_id = c.id)
    where a.person_id = ?
    

    或者我们可以从另一个方向,从项目:

    select a.person_id, b.project_role_id, c.project_id
    from person a join project_role b on (a.id = b.person_id)
    join project c on (b.project_id = c.id)
    where c.project_id = ?
    

    Project::addPerson( Person& ) 应该是 Project::addProjectRole( ProjectRole& ) 项目::addPerson(Person&) 是以下形式的一种方便方法:

    void Project::addPerson( Person& p ) {
      this.addProjectRole( new ProjectRole( p, &this, RoleType::UNASSIGNED ) ;
    }
    

    基本上,我认为:

    2) 有额外数据(何时、何种数据)是关系的标准

        3
  •  0
  •   xtofl Adam Rosenfield    16 年前

        4
  •  0
  •   Jamie Ide    16 年前

    您拥有的是与其他数据、角色的多对多关系。我们有一个类似的结构,除了在我们的案例中,一个人可能在一个项目中扮演多个角色,所以我很难回答同样的问题。一种解决方案是创建一个ProjectPerson类,该类扩展Person并添加role属性:

    public class ProjectPerson : Person
    {
        public string Role { get; set; }
    }
    

    您的Project类现在有一个ProjectPerson集合,但Person类有一个Project集合,因为扩展Project类以添加角色是没有意义的。您必须做一些额外的工作(在ProjectPerson集合中查找此人)才能从此人的角度找到项目中的角色。

    第二种解决方案是处理与其他数据的多对多关系的标准方法。创建一个ProjectRole类,并将其建模为Project和Person两个一对多关系的多方面。也就是说,Project和Person都有一个ProjectRole集合。

    在选择解决方案时,考虑数据访问策略将如何支持模型是非常重要的。您希望避免加载集合需要对集合中的每个对象进行一次或多次数据库访问的情况。

        5
  •  0
  •   Clive Fletcher    15 年前

    似乎有两个主要实体-项目和项目成员。 项目成员具有“成员角色”和“成员名称”属性。这些属性中的任何一个都可能属于一个域,即一组值,这些值可以在查找表中维护,以方便查找和用于搜索。假设有人需要执行特定角色/工作的所有项目成员的信息。

    笔记查找表可以添加条目,但通常不会更改条目的值。一旦从查找表中选择了一个值,则该值将被视为所属表(在本例中为项目成员表)的永久固定装置。

    我不希望在任何业务中看到一个“Person”实体或表,除非像上面这样方便地将其作为查找表。人力资源部门将保留一份员工名单,其中包含工资单等要求的特定信息,但业务部门不需要了解员工的基本情况。注意:定位业务流程以识别实体-不要虚构。