Вопрос доменной модели о наследовании - PullRequest
2 голосов
/ 22 июня 2010

Мне нужен совет по моделированию следующего домена фильмов. У меня есть личность лица. Этот человек может быть актером, режиссером, продюсером и писателем и часто будет всем. Я не хочу дублировать данные в каждой сущности, поэтому лучше создать абстрактный базовый класс 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, которые принимают экземпляр лица, т. Е.

Публичный класс Писатель (Персона, строка attribute1, строка attrribute2) {...}

Ответы [ 4 ]

10 голосов
/ 22 июня 2010

Распространенным решением было бы введение понятия «роль» (вполне уместно в данном случае).Человек может быть актером в фильмах 0+ и / или исполнять роль режиссера.

Это также позволяет добавлять атрибуты к роли, такие как имя персонажа, даты и т. Д.


Редактировать:

Класс Role будет иметь двусторонние ассоциациис человеком и кино.

class Role
{
     public Person Contributor { ... } 
     public Movie  Feature { ... }
     public RoleType Activity { ... }
}  

class Person
{
    public List<Role> Contributions { ... }
}        

class Movie
{
    public List<Role> Contributors { ... }
    ...
}
2 голосов
/ 22 июня 2010

У вас может быть конкретный класс Person со всеми общими сведениями о личности, и тогда у класса person также будет коллекция / список ролей.Роли будут «Актер», «Автор» и т. Д., И у них будут все необходимые дополнительные атрибуты + поведение.

1 голос
/ 22 июня 2010

Если ваши «роли» конечны и могут быть определены заранее (как кажется в вашем примере), вы можете использовать побитовый флаг enum для класса 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);
1 голос
/ 22 июня 2010

Для этого вы должны смотреть на композицию, а не на модель наследования. Довольно стандартный шаблон дизайна для такого рода вещей - на самом деле, я подозреваю (у меня нет копии), что он есть в книге «Шаблоны банд», если вам нужна дополнительная информация.

...