9

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

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

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

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

IvoryCKEditorBundle - 将 textarea 转换为 ckeditor 是在视图文件中的一个 jquery 行中完成的,那么为什么这个包存在呢?我什至不想计算那里的行数。

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

4

1 回答 1

21

表单处理的问题在于它违反了 MVC 的定义。这是一个被称为“横切”的问题,过去已经被科学研究过。例如,论文Domain Driven Web Development With WebJinn是关于该主题的有趣读物。

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

模型:

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

控制器:

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

看法:

  • 表单呈现为 HTML 标记和属性的复杂结构,依赖于上述所有内容(是否需要字段?是否应显示错误?如何对字段进行排序?在下拉列表中提供哪些选择?等)

因此,不可能编写一个不涉及所有这些层的表单抽象机制。相反,解决方案是根据 MVC 将表单库本身构造成满足 SRP 的不同层和子组件。如果您查看 Symfony2 表单组件,它做得非常好。;)

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

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

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

您会看到表单库变得非常复杂。在编写此类“巨大的可怕野兽”时,我们最好的选择是让他们的 API 对于初学者来说尽可能简单,对于更高级的用户来说尽可能灵活,并编写关于充分利用其全部功能的大量文档。最后一点肯定仍然缺乏(请帮助!),但我们一直在努力解决上述所有问题。

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

那么其他更简单的表单库呢?在我看来,这些甚至都没有尝试解决 Symfony2 表单组件已经为您解决的大多数问题。:)

2014 年 1 月 24 日更新:对于任何想了解更多(更多)的人,这是我发表的一篇关于该主题的论文

于 2013-04-19T11:30:15.083 回答