Это когда-либо действительно для преобразования объекта из базового класса в подкласс - PullRequest
13 голосов
/ 16 июня 2009

В моем приложении на данный момент (как и во многих других приложениях) есть сущность с именем Contact, которая представляет любого человека. На самом базовом уровне это используется для представления деловых контактов. Однако его также можно использовать для представления сотрудников компании. и есть также несколько специальных типов сотрудников (скажем, есть один, называемый Manager)

Я пытаюсь смоделировать это как наследственное отношение, которое имеет смысл. Сотрудники имеют имена и адреса, как и контакты, а также ряд атрибутов, связанных с занятостью. У менеджеров также есть ряд специфических для менеджера атрибутов.

Трудность возникает, когда сотрудник получает повышение до менеджера. Можно ли преобразовать базовый класс Employee в класс наследования Manager? Это неправильно. Я думаю, я бы сделал это с помощью специализированного конструктора на Manager.

Помимо этого, NHibernate поддерживает такое поведение? это так просто, как получить сотрудника, создать менеджера из сотрудника, а затем сохранить менеджера?

Ответы [ 6 ]

16 голосов
/ 16 июня 2009

Я бы пошел с композицией за наследование в этом случае. Если вы придерживаетесь наследования, вы будете менять классы с каждым повышением или понижением в должности и каждый раз, когда вы нанимаете контакт или сотрудник уходит и становится постоянным контактом.

Проще сказать, что у контактов есть роли. Вы можете добавить роль менеджера в контакт, чтобы продвинуть его, и удалить роль, чтобы запустить его.

5 голосов
/ 16 июня 2009

Пока ваша бизнес-модель соответствует вашему домену, вы поступаете правильно.

Однако для меня это звучит так: у вас должно быть что-то вроде:

Manager Promote(Employee employee)
{
   var manager = new Manager();
   //promote your employee to a manager here
   return manager;
}

внутри какого-то рабочего процесса какого-то рода.

Что касается NHibernate, похоже, что вы смешиваете логику ORM со своей бизнес-областью. Повышение сотрудника до руководителя является структурой бизнес-домена и, как таковое, относится к вашей бизнес-модели. Однако то, как NHibernate отображает ваших сотрудников и менеджеров в вашу БД, не имеет ничего общего с вашей бизнес-моделью, за исключением того, как их сопоставить. Это, безусловно, не имеет ничего общего с тем, как повысить сотрудника до менеджера.

2 голосов
/ 16 июня 2009

Да, это действительно. В отношении реализации вы можете использовать:

  • Статический метод на менеджере: public static Manager Promote(Employee employee) { ... }
  • Специализированный конструктор по диспетчеру
  • Фабрика или класс обслуживания

Я думаю, что любой из этих подходов был бы хорошим решением. Лично мне нравится специализированное конструкторское решение, поскольку оно хорошо отражает реальный мир: вы создаете нового менеджера из существующего сотрудника.

2 голосов
/ 16 июня 2009

Лично у меня был бы базовый класс со всеми основными вещами и списком ролей.
Каждая роль имеет свои свойства и функциональность.
Преимущества в два раза:

  • Легко дать или взять на себя роль / от человека
  • Это позволит вашим сотрудникам выполнять несколько ролей без необходимости проводить «комбинированные занятия»

Если вы идете с единичным наследованием, то переход с наследованием скоро сделает вас такими классами, как "ManagerProgrammer", "ProgrammerStockManager", "ProgrammerSupport"

0 голосов
/ 21 июня 2009

Контакт является атрибутом Сотрудника. Работник (ваш сотрудник) - это роль, менеджер - это роль. Работник и менеджер по-прежнему являются сотрудниками, но имеют роли. Роль - это отношения IN IN, сотрудник - это отношения AM A, а контакт - это отношения HAS A. Сотрудник имеет контакт (1-1 отношения) Один контакт на сотрудника (1-M, если у них два телефона и т. Д., Но я отвлекся) Сотрудник находится в роли (отношения M-M) Многие сотрудники много ролей Сотрудник А (отношение M-1) - многие сотрудники, все из них.

Итак, вы меняете роли.

0 голосов
/ 16 июня 2009

G'day,

Если вы обнаружите, что вам нужно преобразовать производный класс из одного производного в другой производный тип, то пахнет тем, что первоначальный проект имеет проблемы.

Мое ощущение здесь в том, что вы неправильно представляете объект Manager.

Вернитесь к основам и подумайте в терминах ОО, где ваш базовый класс (контакт) содержит общие элементы объектов Employee и Manager. Любые производные объекты являются просто специализациями базового класса.

В этом случае менеджер не является экземпляром сотрудника?

Как классы Manager, так и класс Employee должны иметь элемент reportTo для данных, который также имеет тип Employee.

Единственное отличие, которое я вижу на данный момент, состоит в том, что объект Manager теперь имеет коллекцию объектов Employee, которые являются их собственными directReports. Вероятно, это должно быть реализовано в виде указателя на контейнер объектов Employee.

Я не могу представить себе какую-либо специализацию в поведении, которая должна отделять объект Employee от объекта Manager.

Хммм, возможно, сделайте базовый класс Person, который содержит контактные данные.

Редактировать: Извините, из вашего комментария, я думаю, я не достаточно ясно. То, что я описал, не приводит к двум отдельным классам, которые напрямую получены из вашего класса Contact, так что вы должны изменить экземпляр Employee на Manager во время выполнения, что было вашим первоначальным вопросом.

То есть я не думаю, что у вас должно быть два производных класса, Employee и Manager, которые наследуются напрямую от вашего класса Contact.

Разве это не те случаи, когда люди работают в компании? Почему следует различать менеджера и сотрудника? Сотрудник больше не является Сотрудником, если он стал Менеджером?

Наличие двух производных классов, менеджера и сотрудника, совершенно неверно. Вы пытались сломать вещи с точки зрения "Иса" и "имеет" отношения. Тогда вы можете увидеть, что ваша базовая структура неверна.

Сказать «isa» Контакт сотрудника просто не имеет смысла. Скорее всего, Сотрудник "isa" Персона и Персона "имеет" набор Контактных данных.

Может быть, вывести класс менеджера как специализацию сотрудника? Сотрудник "isa" Персона. Менеджер "isa" Сотрудник, который "isa" Персона.

НТН

ура

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...