Ok, thanks to you all and this great discussion I want to try to make 
our current project into an MVC-style app, so what now?  This MVC 
discussion could not have come at a better time - our little app is all 
grown up now and needs a real architecture.  I have read the MVC threads 
in depth now, and I have questions.  

WHERE WE ARE NOW
--------------------------  

We have a multiuser application that has about oh, I dunno, 100 
different "screens" to the interface.  They can be roughly divided into 
the following areas - status, admin, registration, reports, and graphs. 
 Most of the actions involve either retrieving data from a database or 
processing a form and inserting into a database (in other words, it's a 
very typical web application).  This application started as a CGI 
script.  For performance reasons, we installed mod_perl and use 
Apache::Registry to run it now.  It's pretty much still a dumb CGI 
script with a mod_perl wrapper, but I did develop a couple of modules to 
do user authentication with AuthCookie-based solutions and tied that 
into Apache::Session for state maintenance between requests.  The CGI 
script has grown to accomodate these ~ 100 actions and is now basically 
a 4,000 line if statement.  The script decides which request to do based 
on a target= parameter passed in (in other words, target=summary or 
target=doctoractivity, etc...).  For sanity's sake, many months ago, we 
switched to HTML::Template (our view) to define our screens, which has 
worked well to date.  On the back end we have PostgreSQL with a healthy 
sized schema of around 150 tables or so that has ~ 350 megs of data and 
on the order of 500,000 transactions a day (lots of data turnover, some 
tables get UPDATEd so frequently as to have 100% data turnover within 15 
minutes).  Anyways, back to the perl part....

Basic code structure:

[snip]
my $dbh = DBI->connect( $r->dir_config('RMSDBI_DSN') , 
$r->dir_config('RMSDBI_user') , $r->dir_config('RMSDBI_password') );

# giant if statement - closest thing I have to a controller, I suppose
if ($target = 'summary') {
  my $tmpl = getTemplate('summary');
  doSummary($dbh,$tmpl);
  print header . $tmpl->output();
} elsif ($target = 'doctoractivity') {
  my $tmpl = getTemplate('doctoractivity');
  doDoctorActivity($dbh,$tmpl);
  print header . $tmpl->output();
} elsif .......

[snip]

# lots of subs basically one per target, closest thing I have to a 
model, I suppose
sub doSummary {
  ($dbh, $tmpl) = shift;
  $sth = $dbh->prepare("SQL STATEMENT HARD-CODED HERE");
  # process result set into hashes and arrays of hashes such as @summary 
that HTML::Template wants
  [snip]
  $tmpl->param(summary => @summary);
}

sub doDoctorActivity {
  ($dbh, $tmpl) = shift;
  $sth = $dbh->prepare("SQL STATEMENT HARD-CODED HERE");
  # process result set into hashes and arrays of hashes such as @summary 
that HTML::Template wants
  [snip]
  $tmpl->param(summary => @summary);
}

etc....

This basic pattern repeated ad infinitum.  It's grown way out of 
control, is a pain to work with, and just feels wrong, very wrong. :-) 
 To be fair, it grew very fast and it was all we (by we I mean the two 
of us that were this entire dept. back then) could do to keep up with 
the feature requests, let alone worry about proper architecting of the 
software.  We're paying for it now, of course.

WHERE WE WANT TO BE
------------------------------

I would like to introduce some semblance of organisation, sanity, 
maintainability, separation of logic, etc.... to this project.  In other 
words, MVC would be a good fit.  

Some of the concrete, basic questions I have are:
1.  Is there one Controller or many?  Should I have one for each main 
area of my site?  /myapp/admin/ goes to an Admin Controller, 
/myapp/reports to another controller, etc...
2.  Does the first part of my code above even remotely resemble a 
Controller?  I mean, it takes the input, calls essentially a 'model' 
object (but passing it the view object, nice, eh? =), but then seems to 
break the model nicely by doing things like printing out the HTML from 
the Controller, etc...
3.  How do you prevent a Controller from just becoming another big if 
statement, or is this their purpose in life?
4.  In the case of a form, what perl structure is used to pass the data 
into the model?
5.  Do you create an actual class for each form?
6.  Do you need to create objects at all?  Is OO a prerequisite to MVC?
6.5.  (thought of while proofreading :-)  Is the statement "there is one 
set of controllers for each defined view" correct?  In other words, if 
we someday want to output the "reports" section of the site as Excel 
spreadsheets in addition to HTML, would we define a new set of 
controllers or how would that work?

Now onto the model, I think I have a little better grasp of the model 
compared to the controller, but I have questions...
7a.  Is it insane to leave my SQL hard-coded in there?  The queries 
don't change all that much, and it's nice to have the query in the same 
place as the processing of the result set so you can kind of "see" the 
structure of the result set better.  This helps our less-experienced 
developers.
7b.  Should I really investigate real object persistence like discussed 
at the POOP site (I have used Tangram with some success on tiny side 
projects but nothing remotely this size)?  Begging the question, should 
I really be migrating to more of an OO style of programming?
7c.  Is there some middle ground that would consolidate our database 
query code but not be a full abstraction layer which I simply think is 
overkill for what we need and for our current talents?
7d.  Or do I -really- want an object/structure that represents every 
result set we need to get back from the database?
8a.  What structures are used to pass back the data from the model 
through the controller to the view?  
8b.  The view is expecting HTML::Template style hashes and arrays, do I 
form these in the model (which seems to be too much knowledge of the 
view while still in the model) or does the controller convert it to the 
structures expected by the HTML::Template view?  
8c.  The model is getting DBI record sets from the db.  I have to put 
this data into -something-, why not the exact format that HTML::Template 
view needs rather than process it twice?
9.  Does the bottom half of my code resemble a model layer at all? 
 Would each of those subs typically become a separate mod_perl module, 
or all live in a library of some sort, etc...begs the question again, is 
this all really supposed to be OO and I'm supposed to have a bunch of 
MyApp::Model::DoctorActivity modules that the controller 'use's?

And finally, the view.  This layer seems to be the 'simplest' of them to 
me since it's really limited in what it can do programmatically (for a 
good reason, I know).
10.  We have situations like "if you are an admin show all three menu 
options, if you are regular joe user, you get one option.  With 
HTML::Template now we handle this like so...getTemplate sets a number of 
standard parameters on each and every template.  Kind of publishing the 
user's session to the template for the template designers to use.  So, 
templates often look like this:

menu option #1
menu option #2
<tmpl_if admin_user>
  Super secret option only admin can see
</tmpl_if>

How does this fit into the MVC model?  Is this an appropriate use of the 
view?  Doesn't "feel" like it is.

These are just some of the many, many questions I have on this topic.  I 
just can't quite get my head around it.  I've got a small window of 
opportunity to introduce some of these concepts into our application but 
I need to be able to understand them a little better.  Some 
stripped-down code samples would be nice (sometimes it's hard to 
decipher real code examples because of all the little quirks and 
intricacies of their specific situation clouding the raw demonstration 
of MVC and how it works), but any feedback at all to my questions would 
be met with wild enthusiasm. =)  Thank you very much and I'm looking 
forward to your feedback.

-Fran

Reply via email to