【问题标题】:Domain model question on inheritence关于继承的领域模型问题
【发布时间】:2010-06-22 22:38:49
【问题描述】:

我需要一些关于为以下电影领域建模的建议。我有一个人实体。这个人可以是演员、导演、制片人和作家,而且通常都是。我不想在每个实体中复制数据,因此最好创建一个名为 Person 的抽象基类,每个 Director、Actor 和 Writer 类都继承自该基类。当我查看以下测试时,这已经开始闻起来了:

[Test] public void Can_Do_It()
{
   var actor = new Actor("Clint Eastwood");  
   var director = //?? Can new it up as he already exists as actor  }

拥有一个 Person 类,然后拥有像 Writer 这样的类来接收 person 的实例是否更可取,即

public 类 Writer(Person 人, 字符串属性 1,字符串属性 2) {...}

【问题讨论】:

    标签: c# domain-driven-design


    【解决方案1】:

    一个常见的解决方案是引入“角色”的概念(在这种情况下非常合适)。一个人可以是 0+ 部电影中的演员,和/或担任导演角色。

    这还允许您向角色添加属性,例如角色名称、日期等


    编辑:

    Role 类将与 Person 和 Movie 有 2-way 关联。

    class Role
    {
         public Person Contributor { ... } 
         public Movie  Feature { ... }
         public RoleType Activity { ... }
    }  
    
    class Person
    {
        public List<Role> Contributions { ... }
    }        
    
    class Movie
    {
        public List<Role> Contributors { ... }
        ...
    }
    

    【讨论】:

    • 感谢 henk 的回复。 Person 和 Actor 的类是什么样的?
    • @Chev :该类将具有角色集合类型的属性......也许:List Roles
    • @Chev:见编辑。 Actor 可以是一个类(Actor 类:Role)或只是 RoleType 枚举的值。
    • 我非常喜欢这种模式,因为一个人可以表演、制作、编写和导演自己的电影,但可能不会被业内其他人视为“成为”演员、制片人,作家或导演。事实上,我怀疑这是洛杉矶一个令人惊讶的常见类别。
    • @Henk-感谢您的回复。我之前实际上已经多次使用过这种模式(尤其是使用权限)。我在这里的问题:1)角色只存在于电影的上下文中。即一个演员只有当他们作为演员被分配给电影时才是演员。所以为了获得演员列表,你不能调用actors.ToList(),而必须调用movies.where(x=>x。 Contributions.RoleType==RoleType.Actor).ToList() 2) 实体特定属性将在所有类型之间共享。如果编写者具有 WGALicence 属性,则该属性需要存在于 Person 类中,并且可能不适用于 Director 角色.
    【解决方案2】:

    你可以有一个具体的 Person 类,其中包含一个人的所有常见细节,然后这个 person 类也有一个角色的集合/列表。角色将是演员、作家等,他们将拥有所有必要的额外属性 + 行为。

    【讨论】:

    • 感谢您的回复。您是否将角色视为具体类是枚举?
    • 我在考虑具体的类,因为这样它们可以存储额外的信息并封装一些行为。
    【解决方案3】:

    您应该为此查看组合而不是基于继承的模型。这类事情的相当标准的设计模式——事实上,如果你想了解更多信息,我怀疑(手头没有副本)它在《四人组》设计模式一书中。

    【讨论】:

    • 感谢您的回复 - 从我现在看到的情况来看,我的代码将显示为: var person = new Person("Clint Eastwood") var actor = new Actor(person); var 导演 = 新导演(人); ?
    【解决方案4】:

    如果您的“角色”是有限的并且可以预先定义(就像您的示例中的情况一样),您可以在 Person 类上使用按位枚举标志。

    class Person {
       [Flags]
       public enum EnumRole {
          None = 0,
          Actor,
          Director,
          Producer,
          Writer
       }
    
       public Person( EnumRole role ) {
          Role = role;
       }
    
       public EnumRole Role { get; set; }
    
       public bool CanDo( EnumRole role ) {
          return (Role & role) != EnumRole.None;
       }
    }
    

    然后创建具有所需角色的人员:

    Person p = new Person(Person.EnumRole.Actor | Person.EnumRole.Director);
    

    ...并检查他们是否具有所需的角色...

    bool canDoIt = p.CanDo(Person.EnumRole.Actor);
    

    【讨论】:

      猜你喜欢
      • 2014-02-24
      • 2011-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-20
      相关资源
      最近更新 更多