我正在开发一个用于管理法庭口译员服务的应用程序(使用Doctrine和Zend Framework 2)。有很多人参与其中,他们有各种专门的角色,因此有一个Person超类和子类。类层次结构在垂直意义上并不复杂——一代继承就足够了——但水平方面给我带来了麻烦。
我认为映射超类不适合我的情况。我也考虑过单表继承,但这很快就会变得很糟糕,因为子类有自己的实体关系,太多的东西无法优雅地塞进一个表中。
这就给我们留下了类表继承,这在大多数方面都非常适合,但是。。。在很多情况下,子类User(用于身份验证)和子类解释器将(或应该)指向父数据表中的同一行,因为它们在现实中代表同一个人。但是,由于鉴别器列的原因,您必须选择其中一个,或者创建两个不同的行来保存相同的数据——规范化警察应该让您这样做。
我认为也许用户或解释器实体必须与Person实体建立一对一的关系,并半手动处理。我认为另一种选择是将User折叠成Person,但这很难看,因为很多人不会进行身份验证,也不会拥有或需要密码。我看过学说继承,几个实体扩展了同一个超级阶级和如何在Doctrine2CTI继承中更改和实体类型(除其他外),但两者都没有解决这个问题。
所以,我想知道是否有人有任何建议。谢谢
听起来你正在管理一堆关于Person
s的数据,这些数据可以识别世界上的个体。由于系统中只有部分人员是Users
,因此我认为有关身份验证、审核日志记录、通知等的关注点与Person
类层次结构的关注点是分开的。
我建议从Person
类层次结构中删除User
。也许可以将其重命名为Account
,让它感觉不那么个人化。Account
可以具有owner
属性,该属性是与Person
的关系。如果您想使用Person
的电子邮件地址作为身份验证的标识符,那没关系。如果您以后想添加username
,那将是Account
的一个属性,因为它只有在该上下文中才有意义。
不确定底层代码(不是ZF开发人员),但我认为您混淆了行为和数据。
要使身份验证工作,您实际上不需要继承。刚刚发现您编写了接口依赖项的ontop代码。
为了让用户能够进行身份验证(而普通人则不能),请使用继承或@timdev建议的关系。在符号世界里,我最好写一些类似的东西
class User extends Person implement UserInterface {
//... implementation
}
class Person {
//...
}
在那之后,您可以确定,您有一个UserInterface
,而任何服务,特别是身份验证。
如果你必须动态切换User
实体的底层类(即你有Author extends Person
,并且希望允许一些作者登录),我认为组合是唯一合适的解决方案。拆分逻辑,拆分实体,拆分数据。要快乐。