Подтвердить что ты не робот

Действительно ли для преобразования объекта из базового класса в подкласс

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

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

Ответ 3

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

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

Если вы идете с одиночным наследованием, идущим с наследованием, в ближайшее время вы получите такие классы, как "ManagerProgrammer", "ProgrammerStockManager", "ProgrammerSupport"

Ответ 4

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

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

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

Ответ 5

G'day,

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

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

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

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

Оба класса Manager и Employee должны иметь член данных reportsTo, который также имеет тип Employee.

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

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

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

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

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

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

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

Говорить Сотрудник "isa" Контакт просто не имеет смысла. Скорее всего, "Сотрудник" isa "Человек и лицо" имеет "набор контактных данных".

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

НТН

веселит,

Ответ 6

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

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