2013-04-02 13 views
9

我越使用Symfony2并与它的形式斗争越多,我得出的结论是它们是一个甚至不应该存在的巨大可怕的野兽。Symfony2表单组件 - 违反了MVC和SRP?

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

这可能是一个不同的问题,但我觉得它是一种相关 - 我也注意到很多关于symfony的尝试可用捆,以解决视图问题的观点外,例如:

KnpMenuBundle - 你在服务器端使用oo-interface生成菜单(为什么不在视图图层所在的位置?)

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

所以它有点像Symfony的核心处处存在这些违规或我只是没有得到它?

+2

这些是第三方工具。尽管Sf2中存在设计缺陷,但实际的框架核心中的SRP违规行为很少,只有在实用的解决方案时才适用。你看到的不是核心。 –

+0

我的意思是说,它好像在Symfony的核心思想中存在某种东西,这会促使人们写出这些疯狂的包。但是,Form组件不是框架的核心组件吗? – moljac024

+0

Zend Framework中有这样的组件,但它非常糟糕。我得出的结论是,创造任何形式的建筑师都是徒劳无益的事情。 –

回答

20

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

举个例子,想想形式MVC的不同层之间的关系:

型号:

  • 形式复制你的域模型(DM)的信息结构。如果您更改此结构(例如,通过向数据结构添加字段或向过程添加参数),则还必须修改表单以输入该信息。
  • 他们需要类型信息从您的DM转换输入到所需的类型。
  • 他们需要知道在您的DM中指定的限制以验证输入。
  • 它们理想地直接从您的DM读取/写入数据(例如,通过读取/写入数据结构的字段或通过调用DM中的过程,将提交的值作为参数)。

控制器:

  • 形式的接收提交的数据并将其发送到DM。
  • 它们根据它们是否成功验证来改变程序流程。

查看:??

  • 形式呈现为HTML标记和属性的复杂的结构,它依赖于上述所有的(如果一个字段被要求应显示错误如何订购字段?在下拉提供什么样的选择?等)

其结果是,不可能写一个形式抽象机制不触及所有这些层。相反,解决方案是根据MVC将表单库本身构建到满足SRP的不同层和子组件中。如果你看看Symfony2表单组件,它的表现相当不错。 ;)

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

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

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

你会发现表单库变得相当复杂。我们写这样的“巨型可怕的野兽”最好的办法是尽可能简化初学者的API,为更高级的用户尽可能灵活,并编写大量关于充分利用其功能的文档。最后一点肯定还是缺乏(please help!),但我们一直在努力完成以上所有内容。

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

那么简单得多的其他表单库呢?根据我的愚见,这些甚至不尝试解决Symfony2 Form组件已经为您解决的大多数问题。 :)

更新2014年1月24日:对于任何想知道更多(更多)的人,这里是a paper that I published on the subject

+0

你介意阐述你认为是*域模型*吗?如果有的话,Symfony窗​​体组件刺激贫血模型... –

+0

让我澄清我在问什么。你说例如:**表格复制你的领域模型(DM)的结构。** 我不能不同意你更强烈的意见。他们应该允许您通过执行表示行为的方法来修改域模型。将您的领域模型放入窗体是构建Form组件的最糟糕的预设之一。 –

+1

我指的是信息结构。如果您的域模型模拟“员工”,并且您有用于修改这些员工数据的表单,那么如果您的域模型的信息结构发生变化,则很可能必须修改表单(例如,您删除出生日期,但添加社会保险号码)。 –