【问题标题】:Relation between entity class and various other entity classes实体类与其他各种实体类的关系
【发布时间】:2020-09-24 12:43:05
【问题描述】:

问题:

在我的 Symfony 4.4 应用程序中有一个 Notification 实体类(通过 Doctrine ORM 2.7 管理)。在现实生活中,每个Notification 对象都可以与一个“主题”相关联。这个“主题”可能是TaskProjectDocumentInvoiceContract等,它们本身都是实体类。

如果有意义的话,理想情况下可以使用Notification::getSubjectNotification::setSubject 方法。如果可能的话,NotificationRepository::findBy('subject' => $subject) 也可以使用——如果这有意义的话。

问题:

使用 Symfony 和 Doctrine ORM 设计 Notification 实体类和所有那些不同的“主题”实体类之间的关系的干净/好方法是什么?是否应该使用 OOP 设计模式?

【问题讨论】:

  • 您可以在通知中添加外键来表示引用者主题;如果通知只能有一个主题,将是 onetoone,如果可以有多个主题,oneToMany,但我认为您想要 OneToOne。
  • 我不知道有任何超级干净的方法可以做到这一点。 Doctrine 确实支持类继承,因此您可以让所有主题类都从 Subject 父级继承。但从 OOP 的角度来看,使用继承可能不是一个好主意。下面的答案更详细地解释了这一点。但是要求诸如 Document 之类的类意识到它们可能是通知的主题并不是很干净。如果您需要另一个关系,例如 Log 实体,这一切都会崩溃。

标签: symfony doctrine


【解决方案1】:

由于您的问题相当模糊,我认为您应该开始定义实体。 一个好的开始方法是创建一个Entity Relationship Diagram。 这是一件好事,首先要考虑 Entity 如何在它们之间进行交互。 在开发新功能时,图表非常有用。

然后,当您清楚地知道自己想要做什么时,您所要做的就是编写代码。

对于你问的问题,我尝试制作这样一个图表,但它可能不完整,因为我不了解你的项目:

当然,我没有代表您描述的每个实体,但您明白了。 这种继承的好处是你可以调用Notification::getSubject,然后你就知道它是哪种主题了

您将创建实体Subject,然后扩展TaskProjectDocumentInvoiceContract 等。

在教义中创建继承:

#src\Entity\Subject
/**
 * @ORM\Table(name="subject")
 * @ORM\Entity(repositoryClass="App\Repository\SubjectRepository")
 * @ORM\InheritanceType(value="JOINED")
 * @ORM\DiscriminatorColumn(name="subject_type", )
 * @ORM\DiscriminatorMap(value={SUB_TYPE_DOCUMENT=Document::class, SUB_TYPE_PROJECT=Project::class, SUB_TYPE_TASK=Task::class})
 */
abstract class Subject{
    const SUB_TYPE_DOCUMENT = 'DOCUMENT';
    const SUB_TYPE_PROJECT = 'PROJECT';
    const SUB_TYPE_TASK = 'TASK';
...
}
#src\Entity\Document
class Document extends Subject{
...
}
#src\Entity\Project 
class Project extends Subject{
...
}
#src\Entity\Task
class Task extends Subject{
...
}

阅读更多:https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/inheritance-mapping.html

这是一种非常经典的方法。现在你问是否有Pattern 可以使用。 想到的可能是Decorator。我建议您阅读它。

如果这些都对您没有帮助,请编辑您的问题并添加有关您需要的更多详细信息...

【讨论】:

  • 非常感谢您的回答。你得到了我的域模型 99% 正确。 :) 您如何看待@Cerad 在我的问题之一中提到的限制/缺点?
  • 是的没错,继承有很多限制,这就是为什么我建议你不要使用它,而更喜欢装饰者模式。如果需要,它甚至可以让你记录事情。我认为 Decorator 是一个很好的模式,因为也许有一天你会想在一个通知中同时添加 TaskProject 。没问题 !您只需在一个通知中“包装”您的任何主题!因为他们都有自己的逻辑!
  • 但是,再一次,我没有得到有关您项目的所有规范,我真的建议您提供更多详细信息或阅读更多关于 Decorator 的信息,而不是将其视为解决方案解决你所有的问题
  • 我认为,如果您的Notification 永远不会包含多个Subject,那么Decorator 可能是矫枉过正......我认为Factoy 模式也很好。 refactoring.guru/design-patterns/factory-method。我想给你带头,但不要相信我的话;)我不假装自己是专家!
猜你喜欢
  • 2017-01-30
  • 2016-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多