【发布时间】:2015-07-27 21:37:43
【问题描述】:
所以我偶然发现了这个障碍,我必须创建一个抽象类和一个工厂来创建更具体的类的对象,这些类扩展抽象类并实现更具体的对象方法。
简单地说,我有一个 SocialMediaAbstract 类。扩展类是 Facebook、Instagram,它们实现了 SocialMediaInterface。 Facebook、Instagram 等都保存在数据库中,带有一个 id、一个名称和几个属性,这些属性都在扩展类中使用,因此是一个抽象类。
因为我希望能够从社交媒体对象中查询一些东西,并且每个社交媒体平台都有自己的 API,所以我制作了接口并创建了不同的类,因此它们都可以拥有自己的这些方法的实现.
现在,问题当然出在我的抽象类和 Doctrine 上。 Doctrine 在他们的website regarding inheritance 上这样说:
映射的超类不能是实体,它不可查询 [...]
现在,如果我有一个 SocialMediaFactory 并输入了一个 ID,我想获取相应的对象,例如 Facebook 或 Instagram 类。当我收集它们时,我不想确切知道它是哪个社交媒体。现在这是教义的问题,至少我认为是这样。
我是否忽略了什么,工厂模式仍然可能吗?或者我真的应该删除抽象类,并创建一个在 SocialMediaInterface 实现类的每个表中搜索的工厂,当应用程序变得更大时,这似乎非常低效且不可维护。
任何见解或指针都将不胜感激,因为我确信这个问题一定会更频繁地出现。我尝试在 Stackoverflow 上进行谷歌搜索和搜索,但找不到任何相关问题或答案。
非常感谢您。
编辑: 我遇到了这个有趣的可能性:Class Table Inheritance。这意味着添加:
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"facebook" = "Facebook", "instagram" = "Instagram"})
我的代码。我寄予厚望,但遗憾的是验证器给了我这个错误:
[学说\ORM\映射\映射异常] 不支持在映射的超类上定义继承信息 s 'Portal\SocialMedia\Entity\SocialMediaAbstract'。
不支持羞耻映射器超类。
编辑 2/结论: 我决定使用类表继承(就像下面建议的答案一样)。从类中删除抽象使得仍然可以使用我的工厂。
我现在使用一个具体类作为一个抽象类,但是感觉不对。我在 docblock 中记录了不应从此类实例化任何对象。
一点旁注:Doctrine 的实体管理器或多或少已经提供了工厂:
$socialMedia = $entityManager->find('Portal\SocialMedia\Entity\SocialMedia', 2);
这将返回一个 Instagram 对象。我仍然建议您在其上构建自己的工厂以便以后进行维护,因为社交媒体实体稍后可能会发生变化。
【问题讨论】:
-
如果需要
class table inheritance,请删除@MappedSuperclass注释。您不再需要它了,它用于不同的继承模式,请参阅我的答案以获得解释:)
标签: php orm doctrine-orm doctrine factory