Php Symfony2表单组件-违反MVC和SRP?

Php Symfony2表单组件-违反MVC和SRP?,php,model-view-controller,design-patterns,symfony,single-responsibility-principle,Php,Model View Controller,Design Patterns,Symfony,Single Responsibility Principle,我越是使用Symfony2并与它的形式斗争,我就越会得出结论,它们是一种巨大的可怕的野兽,甚至不应该真的存在 我看到这篇文章,发现我同意作者的观点。即使这篇文章是针对symfony1.x的,我认为它仍然适用于Symfony2中的表单组件。看起来表单组件确实试图在一个地方解决属于模板、控制器和模型的问题。这是否严重违反了MVC和/或SRP(单一责任原则) 这可能是一个不同的问题,但我觉得这有点相关-我还注意到symfony的许多可用捆绑包都试图解决视图之外的视图问题,例如: KnpMenuBund

我越是使用Symfony2并与它的形式斗争,我就越会得出结论,它们是一种巨大的可怕的野兽,甚至不应该真的存在

我看到这篇文章,发现我同意作者的观点。即使这篇文章是针对symfony1.x的,我认为它仍然适用于Symfony2中的表单组件。看起来表单组件确实试图在一个地方解决属于模板、控制器和模型的问题。这是否严重违反了MVC和/或SRP(单一责任原则)

这可能是一个不同的问题,但我觉得这有点相关-我还注意到symfony的许多可用捆绑包都试图解决视图之外的视图问题,例如:

KnpMenuBundle—您可以在服务器端使用oo接口生成菜单(为什么不在它们所属的视图层中?)

IvoryCKEditorBundle—将textarea转换为ckeditor是在视图文件中的一个jquery行中完成的,那么为什么存在这个捆绑包呢?我甚至不想数一数里面有多少行


因此,在Symfony的核心中似乎到处都有这些违规行为,或者我只是不明白?

表单处理的问题是,它从定义上违反了MVC。这是一个被称为“横切”的问题,过去科学界对此进行过研究。例如,这篇论文是关于这个主题的有趣读物

例如,考虑表单与MVC不同层的关系:

型号:

  • 表单复制域模型(DM)的信息结构。如果更改此结构(例如,通过向数据结构添加字段或向过程添加参数),还必须调整表单以输入该信息
  • 他们需要您的DM提供类型信息,以便将输入转换为所需的类型
  • 他们需要知道DM中指定的约束,以验证输入
  • 理想情况下,它们直接从/向您的DM读取和写入数据(例如,通过读取/写入数据结构的字段,或通过调用DM中以提交的值作为参数的过程)
控制器:

  • 表单接收提交的数据并将其发送给DM
  • 它们根据验证是否成功来改变程序流
查看:

  • 表单呈现为HTML标记和属性的复杂结构,取决于上述所有内容(是否需要字段?是否显示错误?如何对字段排序?在下拉列表中提供哪些选项?等等)
因此,不可能编写不涉及所有这些层的表单抽象机制。相反,解决方案是根据MVC将表单库本身构造成满足SRP的不同层和子组件。如果您查看Symfony2表单组件,它会做得非常好

那么为什么它是如此“巨大可怕的野兽”?第一个问题是抽象。例如,考虑一个简单的下拉列表。如果我们想重用下拉列表的代码,我们需要以某种方式对其进行抽象。现在检查上面的列表,即使这个简单的输入也涉及MVC应用程序的所有三层。你怎么能把一件东西抽象成三个不同的部分呢

第二个问题是特征多样性。表单库永远无法解决开发人员在日常生活中面临的所有问题。因此,所有这些层和抽象机制都需要具有可扩展性,以便您可以使它们的行为完全符合您的要求

虽然表单组件是可扩展的,但它已经解决了数百个小问题,您甚至不必再考虑这些问题。如何输入日期,如何使用不同的UI(下拉列表、复选框、单选按钮等)选择一个或多个选项列表,如何再次保护表单安全漏洞,以及更多我可以撰写文章的主题

您可以看到表单库非常复杂。我们编写这种“巨大的恐怖野兽”的最佳方法是使其API对初学者来说尽可能简单,对更高级的用户来说尽可能灵活,并编写关于充分利用其功能的大量文档。最后一点显然仍然缺少(),但我们仍在继续努力解决上述所有问题

另一方面,将复杂问题简化为简单问题是不可能的

那么其他更简单的表单库呢?依我的拙见,这些甚至不能解决Symfony2表单组件已经为您解决的大多数问题。:)


2014年1月24日更新:对于任何想了解更多信息的人,以下是。

这些是第三方工具。虽然Sf2中存在设计缺陷,但框架实际核心中的SRP冲突是最小的,并且只有当它是实用的解决方案时才适用。你所看到的并不是核心,我的意思是,似乎Symfony的核心思想中存在着某种东西,驱使人们编写这些疯狂的捆绑包。但是表单组件不是框架的核心组件吗?Zend框架中有这样的组件,但它非常糟糕。我得出的结论是,创建任何一种适合所有人的表单生成器都是徒劳的。您会在客户端生成菜单吗?请选择你的话。关注点的分离在KNPENU中维护,标记生成委托给视图层,而菜单层次结构委托给特定类。问题在哪里?我会回答你:用它来创建一个非常简单的3项菜单:)我指的是信息结构。如果您的域模型为“员工”建模,并且您有用于修改这些员工数据的表单,那么您很可能需要