Шаблон проектирования — класс с общими и специализированными свойствами

Я пытаюсь увидеть, есть ли шаблон проектирования, который может решить эту проблему:

Я создал абстрактный класс A со свойствами a, b и c. У меня есть еще один класс B, который расширяет класс A и добавляет больше свойств: x, y, z. Затем у меня есть еще один класс C, который снова расширяет A и добавляет i, j, k. Наконец, у меня есть фабричный метод, который определяет, какой экземпляр создать B или C, и это та часть, где мне нужна помощь. Как или что должен возвращать этот фабричный метод: если он возвращает экземпляр A, то я не знаю, какой конкретный экземпляр был создан B или C? Мне нужен этот фабричный метод для создания конкретного экземпляра. Теперь я знаю, что мог бы написать статический метод, такой как createB или createC, но я ищу более общее решение, возможно, другой шаблон проектирования здесь.

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


person Ahmed Bhaila    schedule 29.10.2012    source источник


Ответы (6)


Я бы сохранил Factory Pattern как следует. поэтому возвращаемый тип будет классом Abstract A. B и C также должны наследовать свои свойства через шаблон прокси.

Итак, создайте интерфейсы CAable и BAble и используйте C и B в качестве экземпляров A (поскольку они оба генерируются одной и той же фабрикой), а затем приведите B и C, чтобы они действовали как их интерфейсы.

Ваше здоровье!

ОБНОВИТЬ:

Кажется, я понял, что вам нужно, представьте себе следующее: На школьной странице. Существует общий вид «Студенты и преподаватели», у обоих есть общие и отдельные поля, но общий запрос — schoolMember.

class SchoolMember // The return type of your Factory
  -name
  +getView():SchoolMemberView // Will be used by the View//View Model

Interface Professor
  getProfession()
Interface Student
  getSemester() 

class FacultyMamber: SchoolMember,Professor
  -profession
  +getView():SchoolMemberView
class UniStudent: SchoolMember,Student
  -semmester
  +getView():SchoolMemberView
person Evan P    schedule 29.10.2012
comment
Привет, у меня похожая проблема. Но с вашим примером я не понимаю, как мы можем получить доступ к специализированным свойствам, если фабрика возвращает только экземпляры SchoolMember. Как в таком случае получить доступ к профессии или семестру? - person Carlos Ferreira; 15.12.2015
comment
через геттеры и сеттеры? - person Evan P; 15.12.2015

Судя по вашему описанию, и B, и C не имеют ничего общего с A. Вы упомянули, что каждый класс имеет определенные свойства, но ничего не сказали о том, что у них общего / как они связаны. Если между вашими классами нет связи, вы не должны использовать наследование.

Однако, если есть общие отношения, которые вы не упомянули в своем вопросе, шаблон фабричного метода вероятно, это то, что вы ищете.

person Aidanc    schedule 29.10.2012
comment
Я упомянул, что и класс B, и C расширяют A, поэтому B и C имеют свойства a, b и c вместе с некоторыми дополнительными свойствами, проблема с Factory в том, что он вернет экземпляр класса A, тогда как я ищу что-то большее бетон с точки зрения B или C - person Ahmed Bhaila; 29.10.2012

Единственное, что приходит на ум при чтении вашей проблемы, это абстрактный фабричный шаблон:

http://en.wikipedia.org/wiki/Abstract_factory_pattern

person sampson-chen    schedule 29.10.2012

Фабричный метод должен возвращать экземпляр A. Если вам нужно знать, является ли конкретный объект B или C, вы можете использовать оператор instanceof, который является шаблоном Reflection. В идеале вам не нужно знать, есть ли у вас B или C; вся эта логика должна обрабатываться полиморфизмом методов в A.

person antlersoft    schedule 29.10.2012
comment
на самом деле единственная причина, по которой мне нужно знать конкретный экземпляр, заключается в том, что я передаю этот экземпляр внешнему jsp, и этот jsp будет вызывать геттеры для свойств для рендеринга. - person Ahmed Bhaila; 29.10.2012

Именно то, что указано в качестве предупреждения в описании шаблона Factory.

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

if (genericProduct typeof ConcreteProduct)
    ((ConcreteProduct)genericProduct).doSomeConcreteOperation();

Источник: http://www.oodesign.com/factory-method-pattern.html

person Arun Manivannan    schedule 29.10.2012
comment
Это антишаблон масштабируемости. Представьте себе 5к условий typeof. - person Evan P; 29.10.2012

Я бы предложил Builder pattern, который будет знать, какой объект строить на основе специализированного поля, установленного для Builder. .

person Buhake Sindi    schedule 29.10.2012
comment
Думаю, нет. Builder строит композит и используется, когда конструкция объекта является сложной. Из вопроса мы могли понять, что у пользователя нет проблем с созданием объекта. Просто подклассы настолько специализированы, что он должен знать, какая это реализация суперкласса. - person Arun Manivannan; 29.10.2012