フォーム処理の問題は、定義上 MVC に違反していることです。これは「クロスカッティング」として知られる問題で、過去に科学によって研究されてきました。たとえば、論文Domain Driven Web Development With WebJinnは、このトピックに関する興味深い読み物です。
例として、フォームと MVC のさまざまなレイヤーとの関係について考えてみましょう。
モデル:
- フォームは、ドメイン モデル (DM)の情報構造を複製します。この構造を変更する場合 (たとえば、データ構造にフィールドを追加したり、プロシージャにパラメータを追加したりして)、その情報を入力するためのフォームも調整する必要があります。
- 入力を必要な型に変換するには、DM からの型情報が必要です。
- 入力を検証するには、DM で指定された制約を知る必要があります。
- 理想的には、DM との間で直接データを読み書きします (たとえば、データ構造のフィールドを読み書きするか、送信された値をパラメーターとして DM でプロシージャを呼び出すことにより)。
コントローラ:
- フォームは送信されたデータを受け取り、DM に送信します。
- 検証が成功したかどうかに応じて、プログラム フローを変更します。
意見:
- フォームは、上記のすべてに依存する HTML タグと属性の複雑な構造としてレンダリングされます (フィールドを必須にする必要があるか、エラーを表示する必要があるか、フィールドの順序をどのようにするか、ドロップダウンで提供する選択肢は何かなど)。
したがって、これらすべてのレイヤーに触れないフォーム抽象化メカニズムを作成することは不可能です。反対に、解決策は、フォーム ライブラリ自体を MVC に従って、SRP を満たすさまざまなレイヤーとサブコンポーネントに構造化することです。Symfony2 の Form コンポーネントを調べてみると、かなりうまく機能しています。;)
では、なぜ「巨大で恐ろしい獣」なのか?最初の問題は、抽象化の問題です。たとえば、単純なドロップダウンを考えてみてください。ドロップダウンのコードを再利用したい場合は、何らかの形で抽象化する必要があります。上記のリストを確認してください。この単純な入力でも、MVC アプリケーションの 3 つのレイヤーすべてに影響します。3 つの異なる部分に構造化されることを意図したものをどのように抽象化できますか?
2 つ目の問題は、機能の多様性です。フォーム ライブラリは、開発者が日常生活で直面するすべての問題を解決するわけではありません。したがって、これらすべてのレイヤーと抽象化メカニズムは拡張可能である必要があり、それにより、それらを希望どおりに動作させることができます。
拡張可能である一方で、Form コンポーネントはすでに何百もの小さな問題を解決しており、それらの問題について考える必要さえありません。日付を入力する方法、さまざまな UI (ドロップダウン、チェックボックス、ラジオ ボタンなど) を使用して選択肢のリストから 1 つまたは複数を選択する方法、フォームをセキュリティ上の欠陥から保護する方法など、エッセイを書くことができるトピックは他にもたくさんあります。約。
フォーム ライブラリが非常に複雑であることがわかります。このような「大規模な恐ろしい獣」を作成する際の最善の策は、API を初心者向けにできるだけシンプルにし、上級ユーザー向けにできるだけ柔軟にし、そのフルパワーの活用に関する広範なドキュメントを作成することです。最後の点は間違いなくまだ不足しています (助けてください! ) が、私たちは上記のすべてに継続的に取り組んでいます.
一方、複雑な問題を単純な問題に還元することは、残念ながら不可能です。
はるかに単純な他のフォーム ライブラリについてはどうでしょうか。私の謙虚な意見では、これらは Symfony2 フォーム コンポーネントが既に解決している問題の大部分に対処しようとさえしていません。:)
2014 年 1 月 24 日更新:もっと (もっと) 知りたい人のために、この件に関して私が公開した論文を以下に示します。