Итак, я наткнулся на это препятствие, когда мне нужно создать абстрактный класс и фабрику для создания объектов более конкретных классов, которые расширяют абстрактный класс и реализуют более конкретные методы объекта.
Проще говоря, у меня есть класс SocialMediaAbstract. Расширяющиеся классы - это Facebook, Instagram, и они реализуют SocialMediaInterface. Facebook, Instagram и т. Д. Все сохраняются в базе данных с идентификатором, именем и несколькими другими свойствами, которые используются среди расширяющихся классов, следовательно, абстрактный класс.
Поскольку я хочу иметь возможность запрашивать несколько вещей из объектов SocialMedia, а каждая платформа социальных сетей имеет свои собственные API-интерфейсы, я создал интерфейс и создал различные классы, чтобы все они могли иметь свои собственные реализации этих методов.
Теперь проблема, конечно, связана с моим абстрактным классом и Doctrine. Doctrine сообщает об этом на своем веб-сайте, посвященном наследованию:
Сопоставленный суперкласс не может быть сущностью, он не поддерживает запросы [...]
Теперь, если бы у меня был SocialMediaFactory и я добавил идентификатор, я бы хотел вернуть соответствующий объект, например, класса Facebook или Instagram. Я не хочу точно знать, что это за SocialMedia, когда я их собираю. Это проблема доктрины, по крайней мере, я так думаю.
Я что-то упускаю, возможен ли заводской шаблон? Или мне действительно стоит просто удалить абстрактный класс и создать фабрику, которая выполняет поиск в каждой таблице реализующего класса SocialMediaInterface, что кажется крайне неэффективным и незаметным, когда приложение становится больше.
Мы будем благодарны за любую информацию или указатели, поскольку я уверен, что эта проблема должна возникать чаще. Я пробовал гуглить и искать в самом Stackoverflow, но не смог получить никаких соответствующих вопросов или ответов.
Заранее большое спасибо.
РЕДАКТИРОВАТЬ: Я столкнулся с такой интересной возможностью: Наследование таблицы классов. Это означало бы добавить:
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"facebook" = "Facebook", "instagram" = "Instagram"})
к моему коду. Я возлагал большие надежды, но, к сожалению, валидатор выдал мне эту ошибку:
[Doctrine \ ORM \ Mapping \ MappingException] Не поддерживается определение информации о наследовании для сопоставленного суперкласса Portal \ SocialMedia \ Entity \ SocialMediaAbstract.
Суперклассы преобразователя стыда не поддерживаются.
РЕДАКТИРОВАТЬ 2 / ЗАКЛЮЧЕНИЕ: Я решил пойти с наследованием таблицы классов (точно так же, как предложенный ниже ответ). Удаление абстракции из класса позволило по-прежнему использовать мою фабрику.
Однако сейчас я использую конкретный класс как абстрактный, что кажется неправильным. Я задокументировал в docblock, что никакие объекты не должны создаваться из этого класса.
Одно небольшое примечание: Entity Manager Doctrine более или менее уже предоставляет Factory:
$socialMedia = $entityManager->find('Portal\SocialMedia\Entity\SocialMedia', 2);
Это возвращает объект Instagram. Я по-прежнему предлагаю вам построить над ним свою собственную фабрику для удобства обслуживания в дальнейшем, поскольку сущность SocialMedia может измениться позже.
@MappedSuperclass
, если хотитеclass table inheritance
. Он вам больше не нужен, это для другого шаблона наследования, см. Мой ответ для объяснения :) - person SaSchu   schedule 28.07.2015