2013-04-02 15 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

我指的是信息結構。如果您的域模型模擬「員工」,並且您有用於修改這些員工數據的表單,那麼如果您的域模型的信息結構發生變化,則很可能必須修改表單(例如,您刪除出生日期,但添加社會保險號碼)。 –