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!
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.)