Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 Form component - violating MVC and SRP?

The more I use Symfony2 and struggle with it's forms the more I come to the conclusion that they are a massive scary beast that shouldn't even really exist.

I have come upon this article here and I find that I agree with the author. Even if the article is for Symfony 1.x I think it still holds for the Form component in Symfony2. It really seems like the form component tries to solve problems that belong in the template, controller and model, all in one place. Doesn't this severely violate the MVC and/or SRP (Single responsibility principle)?

This may be a different question but I feel it is kind of related - I have also noticed that a lot of the available bundles for symfony try to solve view issues outside the view, for example:

KnpMenuBundle - you generate menus on server side with an oo-interface (why not in view layer where they belong?)

IvoryCKEditorBundle - converting textarea to ckeditor is done in one jquery line in the view file, so why does this bundle exist? I don't even want to count the number of lines in there.

So it kind of seems like there are these violations everywhere in the core of Symfony or am I just not getting it?

like image 572
moljac024 Avatar asked Apr 02 '13 10:04

moljac024


1 Answers

The problem about form processing is that it violates MVC by definition. This is a problem known as "crosscutting" and has been studied by science in the past. The paper Domain Driven Web Development With WebJinn, for example, is an interesting read about the topic.

As an example, think about the relation of forms to the different layers of MVC:

Model:

  • Forms replicate the informational structure of your domain model (DM). If you change this structure (e.g. by adding fields to a data structure or by adding parameters to a procedure), you must also adapt the forms for entering that information.
  • They need type information from your DM to convert input to the types required there.
  • They need to know the constraints specified in your DM to validate the input.
  • They ideally read and write data directly from/to your DM (e.g. by reading/writing fields of a data structure or by invoking a procedure in the DM with the submitted values as parameters).

Controller:

  • Forms receive submitted data and send it to the DM.
  • They alter the program flow depending on whether they validate successfully or not.

View:

  • Forms render as a complex structure of HTML tags and attributes that depends on all of the above (Should a field be required? Should errors be displayed? How to order the fields? What choices to offer in a drop-down? etc.)

Consequently, it is impossible to write a form abstraction mechanism that does not touch all of these layers. The solution, on the contrary, is to structure the form library itself according to MVC, into different layers and sub-components that fulfill the SRP. If you look into the Symfony2 Form component, it does so pretty well. ;)

So why is it such a "massive scary beast"? The first problem is that of abstraction. Think of a simple drop-down for example. If we want to reuse the code for the drop-down, we need to abstract it somehow. Now check the list above, even this simple input touches all three layers of an MVC application. How can you abstract something that is meant to be structured into three different parts?

The second problem is feature diversity. Form libraries never solve all the problems that developers face in their daily lives. So all these layers and abstraction mechanisms need to be extensible so that you can make them behave exactly like you want them to.

While being extensible, the Form component already solves hundreds of tiny problems that you don't even have to think about anymore. How to input dates, how to select one or many of a list of choices using different UIs (drop-downs, checkboxes, radio buttons, etc.), how to protect forms again security flaws and many more are topics that I could write essays about.

You see that form libraries turn out to be quite complex. The best bet that we have at writing such "massive scary beasts" is to make their API as simple as possible for beginners, as flexible as possible for more advanced users and to write extensive documentation about leveraging its full power. The last point is definitely still lacking (please help!), but we're continually working on all of the above.

Reducing a complex to a simple problem, on the other hand, is unfortunately not possible.

What about other form libraries out there that are so much simpler? In my humble opinion, these don't even try to address a majority of the problems that the Symfony2 Form component already solves for you. :)

Update January 24, 2014: For anybody that wants to know more (much more), here's a paper that I published on the subject.

like image 182
Bernhard Schussek Avatar answered Sep 29 '22 04:09

Bernhard Schussek