2009-06-16 2 views
13

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

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

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

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

ответ

5

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

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

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

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

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

+0

Вопрос NHibernate состоял в том, чтобы узнать, будет ли NHibernate жаловаться на сохранение объекта в качестве подкласса, когда он был восстановлен в качестве базового типа. –

2

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

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

Если вы идете с одного inherritance происходит с inherritance будет вскоре сделать вас с классами, как «ManagerProgrammer», «ProgrammerStockManager», «ProgrammerSupport»

16

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

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

+1

Это должно быть отмечено как правильный ответ – Pierreten

0

G'day,

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

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

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

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

Классы Менеджера и Сотрудника должны иметь отчетность для члена данных, который также имеет тип Employee.

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

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

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

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

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

Не являются ли эти случаи людьми, которые наняты компанией? Зачем различать Manager и Employee? Является ли сотрудник больше не Работником, если он становится Менеджером?

Имея два производных класса, Менеджер и Сотрудник, является полностью неправильным ИМХО. Вы пробовали ломать дело в терминах «isa» и «имеет» отношения. Тогда вы можете видеть, что ваша основная структура неверна.

Говорить Сотрудник «isa» Контакт просто не имеет смысла. Более вероятно, что Сотрудник «isa« Человек и лицо »имеет« набор контактных данных ».

Возможно ли получить класс Менеджера в качестве специализации сотрудника? Сотрудник «isa» Person. Менеджер «isa» Сотрудник, который «isa» Person.

НТН

веселит,

+0

Простите, что это совсем не помогает. Вы говорите, что я неправильно представляю менеджера, а затем подробно описываю, что я предлагаю. –

+0

Извините. Вы все еще описываете то, что у меня уже есть. наследование от Contact -> Employee -> Manager. Семантическая разница между человеком и контактом является релевантной. На вопрос задано это наследование, нормально ли конвертировать сотрудника в подкласс сотрудника (Менеджер). –

2

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

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

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

+1

Не забывайте, что сотрудник Demote (менеджер менеджера) и Employee Hire (контактный контакт) и менеджер HireAsManager (контактный контакт). –

0

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

Значит, вы меняете роли.

Смежные вопросы