MVC Logic

Ovid on 2007-06-15T09:30:32

Model
Business logic goes here
View
Presentation logic goes here
Controller
Application logic goes here

Here's a typical bit of "controller" logic:

sub add_product_to_order {
    my ( $dbh, $p_id, $o_id ) = @_;
    unless ( $o_id && $o_id =~ /^\d+$/ ) {
        dienice("Bad order number $o_id");
    }

    my $o_sql = 'SELECT * FROM orders   WHERE id = ?';   
    my $p_sql = 'SELECT * FROM products WHERE id = ?';   

    my $order   = $dbh->selectrow_hashref($o_sql, {}, $o_id);
    my $product = $dbh->selectrow_hashref($p_sql, {}, $p_id);
    # snip
    my $html = <<'END_HTML';
    
       ...
}

That's crap. It's all crap. But that's what's usually out there. Here's a better version.

sub add_product_to_order {
    my ( $self, $o_id, $p_id ) = @_;

    my $order   = Order->new($o_id)   or $self->add_error(Order->error);
    my $product = Product->new($p_id) or $self->add_error(Product->error);
    $self->handle_errors;   # doesn't return if errors

    $order->add_to_basket($product);
    $self->show_basket($order);
}

That still has some problems, but it's much cleaner, the model and view logic is more clearly separated and it's easier to read. This should be more of your end goal. Stop writing crap like the first example!


Step 1: Use MVC

Purdy on 2007-06-15T12:56:46

What you're probably seeing is someone's first approach or someone who refuses to grow in their skills (which your post should help enlighten). I look at that first example and am repulsed, but at the same time, I remember writing code like that when I first started w/ MVC.

I'm a big fan of CGI::Application, where you write subclasses that are Controllers. Within that subclass, you write subs that handle states of the webapp and yeah, when you first pick it up, you find yourself putting HTML and SQL code in there, but as you learn and evolve, there's either support built-in to cgiapp or plugins that offer support for templates, db abstraction, etc.

- Jason

Re:Step 1: Use MVC

Ovid on 2007-06-15T13:49:58

That's another reason why I rather like Catalyst and Jifty -- cleaner separation of concerns. While CGI::Application doesn't do as much heavy lifting, it still seems like a much better idea that what most folks do. Plus, if you can at least remember to keep the three logic types in their appropriate layers, you make refactoring much easier because of the looser coupling.

And years ago, I wrote code like my first example, too. In fact, I remember when chromatic came and worked at the same company I did and I apologized to him for how bad my code was. It was a very humbling experience (it still wasn't as bad as that first example, but it was pretty bad).

Re:Step 1: Use MVC

chromatic on 2007-06-15T16:43:30

Any deployed codebase used by actual customers and funded by people who won't put up with infinite deadlines has some technical debt. Your code wasn't the problem. (At least, I can't remember ever having to fix a bug in code you'd written.)