Symfony2 MVC:我的代码属于哪里


Symfony2 MVC: where does my code belong?

我想澄清是把代码放在控制器、实体还是制作服务中。

我有"cardset"answers"card"对象(后者中的许多嵌入在前者MongoDB中),由普通的PHP类/对象表示。这些包含属性,例如"id"、"postal_address"。

我有一个生成卡片PDF的方法。目前,我在"卡"对象中有它,所以我可以从控制器调用:

$card->makePDF()

对我来说,这似乎很干净,但我怀疑我错了。

如果我把所有的逻辑都放在控制器中,那么控制器就会变得又长又难用,而且我不确定控制器是否是作用于我的对象的方法的位置。这就是服务的目的吗?

试着总结一下:一个对象是否应该知道它可以"对自己"做的所有常规事情,并将它们作为成员函数放在内部,或者是否应该将其他方法传递给对象以进行操作。如果是,这些方法应该保存在哪里?

我很确定它不是"存储库",因为它似乎只是帮助检索/存储实体。

谢谢!

简短回答:

PDF生成应该是一种服务,而不是对象上的方法。

更长的答案:

一般来说,尤其是在Symfony2中,模型应该只用于存储数据。控制器用于处理模型之间的关系,视图用于以人类或计算机可读的形式表达数据。服务用于不符合上述任何一种情况的事情,这些事情与web应用程序的状态无关。

发送电子邮件就是一个很好的例子。电子邮件包含数据(模型)。用户已发送电子邮件(控制器)。电子邮件看起来有一种特定的方式(视图)。然而,实际发送电子邮件的行为与网络应用程序的状态无关(该服务只知道它被要求向这些人发送此电子邮件)。因此,有一个独立的服务只处理发送电子邮件是有道理的。

类似地,生成PDF文件的行为与web应用程序的状态无关。PDF生成器不需要知道你的应用程序中发生了什么,它只知道它被要求制作PDF。

  • Symfony2不是MVC结构(正如Fabien自己所说),正是因为它给出了所有的V(树枝)和C(控制器),但没有给出M部分。M部分是"免费"的,可以根据您的需要进行构建。

  • 有一个主要的困惑,人们"认为"教义就是模式。但事实并非如此。我们所做的是Bundle中的两个目录,一个为Doctrine ODM类称为"Document",另一个为"Model",其中包含"业务逻辑"。

就我个人而言,$card->makePDF()是有意义的。。。

但$card应该是一个"模型卡",它继承或有一个底层对象"数据卡",即条令类。

您可以使用继承、接口、创建者或任何您想将"模型卡"与"数据卡"联系起来的东西,但关键是"原则不是商业模型",它只是一个持久层,您的模型是"普通类",您可以构建这些类来将数据包入其中,并使控制器使用模型,而不是数据。

如果您遵循SOLID原则,您将获得SRP,该SRP规定您的类应该有一个单一的责任。

我认为很明显,生成一个pdf与建模数据和映射数据库(您的实体就是这样做的)

不同