Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Why I dislike the MVC implementations in Web

by ruoso (Curate)
on Jun 07, 2005 at 19:11 UTC ( [id://464418]=perlmeditation: print w/replies, xml ) Need Help??

MVC is a good pattern, after working with the Swing implementation I saw it could be really usefull. But I didn't have the same pleasure when working with MVC in Web.

The question is that the Web MVC is not actually MVC (as it was first defined). Some has called it MVC2. A good example of the MVC(2) implementation is the Struts (in Java), and CGI::Prototype (in Perl).

So, before explaining why I don't like the MVC2, there are one thing to consider. What I'll say only applies to complex information systems, not to small few-forms cgi applications where this model fits very well.

MVC stands for Model-View-Controller, which means that the interface will be splitted in three parts:

  • The Model is supposed to have the information the View needs to be rendered.
  • The Controller is supposed to change the model and the view according to specified actions.
  • The View is supposed to render something to the user *and* receive the input by sending messages to the controller which would change the model which would notify the view, or change the model directly and receiving the notify back.

This is how the swing implementation works (and I think) how smalltalk did (that's just a bet).

Which is the difference from this definition to the MVC2 (the currently implemented MVC for Web)?

The big difference is that one important responsability is taken from the view and delegated to the controller, which is processing the user input. For instance, in MVC2, if you have a datetime field splitted in two inputs, the View AND the Controller should know about that, because the View will split the datetime into the appropriate fields, and the Controller would put it back before sending to the model.

In the original MVC definition, the only part that would know about the different inputs for the same value would be the View, which would encapsulate this logic.

For a simple interface that's not too bad, because you can simply do the work that way and it will work very well, but in a complex system when you have more complex fields (like a calendar, or a set of radioboxes, or a set of checkboxes, or worst, this all together in several forms, this will become a pain.

I have a proposed solution to this problem in the Perl Oak (http://perl-oak.sf.net) component model, where each implementation is required to render itself and process the request from the user. But I made mistakes in the first version and I'm starting the Oak2 from scratch (using Template::Toolkit and other nice modules). I'd like to hear comments about the presented problem and possible solutions.

  • Comment on Why I dislike the MVC implementations in Web

Replies are listed 'Best First'.
Re: Why I dislike the MVC implementations in Web
by perrin (Chancellor) on Jun 07, 2005 at 20:41 UTC
    It sounds like you're complaining about the way the different pieces are named. Who cares? You're right that the way Smalltalk defines things is not the same as most web versions do it, but that doesn't diminish the usefulness of the architecture. Jamming the logic for processing input and the logic for displaying it into one "component" doesn't seem like an improvement -- that will just make it hard to change the presentation when you need to.

    To me, the bottom line is that a web architecture must support having a designer who doesn't know Perl working on the HTML. Template oriented structures like MVC do this well. Your architecture doesn't look like it will.

      Well, and that's why I said this only applies to complex information systems. This model fits very well for small applications that a designer will create the HTML for each page. For a bigger application, this starts to be a problem for maintainance of the software, and reduces the re-usability of the code.

      BTW, the "component" model can be easy to designers, it's just a matter of creating a template file for each component, and allowing an entire form to be designed in a template, *BUT* instead of defining the HTML of each component, calling the desired component's render method, which would use a separated template and a separated render code, which would enable re-use and encapsulation of complex widgets (like the mentioned datetime field).

      The first version of Oak doesn't use templates, really. But the model do allows me of using in the second version, which I will.

      And... I'm not complaining about the naming, I just wanted to clarify that the Web implementations of MVC are not quite MVC, and that it would be nice if it was.

Re: Why I dislike the MVC implementations in Web
by siracusa (Friar) on Jun 08, 2005 at 02:01 UTC
    The big difference is that one important responsability is taken from the view and delegated to the controller, which is processing the user input. For instance, in MVC2, if you have a datetime field splitted in two inputs, the View AND the Controller should know about that, because the View will split the datetime into the appropriate fields, and the Controller would put it back before sending to the model.

    Not the way I do it, although I'm not sure what I'm doing is any more "pure" MVC. It's just what works for me. Anyway, I modularize my forms and fields so that neither the view or the controller have to worry about stuff like this. The form object simply says "I have a split MDY date field called 'start_date.'"

    package MyEditForm; ... sub build_form { ... $self->add_field(start_date => MyDateField::MDY->new(size => ...)); }
    The application associates the form with a page:
    package MyWebApp; ... sub init { ... $self->add_forms ( edit_form => { class => 'MyEditForm', ... }, ... )l $self->add_pages ( edit_page => { form_names => [ qw(edit_form ...) ], path => 'edit.html', ... }, ... ); ... }

    Asking the app to show the page will init the form and pass it to the page.

    sub do_whatever { ... $app->show_page('edit_page'); }

    From with the page, it's trivial (but templating-language-specific) to print the "start_date" field as XHTML (Mason example):

    <!-- file: edit.mc --> <html> ... <% $form->start_html %> <% $form->field('start_date')->html %> ... <% $form->end_html %> </html> <%args> $form </%args>

    Nowhere does anyone have to be aware that "start_date" is a split field--not even in the query parameters. These would both work transparently:

    /mywebapp/edit?start_date=1/2/2005 /mywebapp/edit?start_date.month=1&start_date.day=2&start_date.year=200 +5

    Ditto for setting fields directly:

    $form->field('start_date.day')->input_value(1); $form->field('start_date')->field('day')->input_value(1);
    $form->field('start_date')->input_value('1/31/1988'); $form->field('start_date')->input_value(DateTime->new(...));

    And so on. My webapp passes query params down to the form object as a hash. No heroics necessary. The form object can init its fields based on that hash, doing any necessary subfield initialization. Form objects can also be initialized with model objects:

    $edit_form->init_with_product($product)

    Individual fields can be set with objects when appropriate (e.g., DateTime objects) from within the controller (or the view if it's embedded-perl-ish like Mason). Finally, my views just call methods on field objects to produce the appropriate HTML.

    Abstracting forms (and by extension, fields) is a big, big win for webapps IME. It lets each piece of "MVC" act as is appropriate to itself without sweating "external" details.

      Well,

      It seems you're implementing the same component model I am talking about... Could you please point me to the module where you implement that? I'd like to take a look as an inspiration for Oak2.

        It's actually suite of modules under the name "Rose"

        The webapp component is not yet on CPAN, but the HTML forms and database objects are up, both of which are useful outside of the rest of the Rose framework.

        I hoped to have a development version of the webapp module up by now but I've been sidetracked with other work. My new goal is to get it uploaded by the end of the summer...

Re: Why I dislike the MVC implementations in Web
by johnnywang (Priest) on Jun 07, 2005 at 20:34 UTC
    In Struts, there's some confusion/disagreement about which part of MVC the ActionForm beans belong to. The official documentation puts it in the Model part, but also says it should be considered as part of Controller. I always consider it as part of the View. With the ValidatorForm and the various taglibs, I would consider the combination of JSP/taglib and ActionForm to be a reasonably good View component.

    In perl frameworks, I've only used CGI::Application with TT2, and ValidateRM. The only one I miss is the equivalent of taglibs (those in the Struts html namespace). I heard TT2 can/already do that.

      The question is that if you have a template to represent the entire page (including the inputs), you can't actually reuse complex inputs. Because something is missing *before* the validator to put the pieces together of the complex input. Think in a datetime field splitted in:

      ___/___/___ __:__:__
      

      This means six input fields representing a single value. The validator (AFAIK) expects a complete value, not the tiny bits of it.

        Of course you can reuse them. There is a certain amount of coordination required between the HTML and the code that parses the input. Your component model will not change that.

        If you wanted to you could do that bit in JavaScript and send it as a 7th parameter, so the code would still be part of the view...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://464418]
Approved by tlm
Front-paged by matthewb
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (3)
As of 2024-03-29 15:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found