-- Mark Stosberg <[EMAIL PROTECTED]> wrote
(on Saturday, 02 October 2004, 02:35 AM +0000):
> On this list there was just a thread which brought to light how 
> people access databases through CGI::Application. There were three primary
> groups of answers:
>  1. Custom SQL called directly from the CGI::Application project. 
>  2. Using custom  "Data Access Objects" to abstract the issue 
>  3. Using Class::DBI as a standard solution.
> 
> I'd like to discuss this issue a little more broadly: What's an
> effective way to to structure your application once you realize it makes  
> sense to move some logic into helper modules? Munging data as it comes 
> in and out of the database is probably the most common need for this.
> 
> Here are some approaches I can think of:
> 
> 1. A purely orthogonal module
> 
> Here, the helper module has no dependency or relation to
> CGI::Application. Most other modules you might employ from CPAN would
> fall into this category. For example, using CGI::Simple, SQL::Abstract
> or Data::Grouper.
> 
> In many ways, this is the ideal setup, because the lack of
> interdependence reduces the overall complexity of your application. 
> 
> Unfortunately, writing this of module for a custom solution can tedious
> if there /are/ a lot of interdependencies you want to consider, such as
> sharing configuration data, a database handle, session information or
> CGI query parameters. 

This is the way I write my applications. I came to this from a variety
of directions:

1. MVC pattern -- to which I was introduced via CGI::App, suggests that
   the business logic code is orthagonal to the view code is orthagonal
   to the controller code. Now, the controller falls into a wierd area
   in that it needs to communicate between two orthagonal systems, but I
   find that that's actually fairly easily done. The way I write my
   systems, the controller simply worries about processing the input,
   using that (filtered) input to pass data to the model, process the
   response from the model (if necessary) and pass that data to the
   view. It's not completely orthagonal to the view, as the view may
   require certain input and forms of input -- which means if the view
   changes, the controller may need to change as well.

   It makes for some work at the beginning -- but in the end very much
   simplifies everything. I think of my model as an API -- it expects
   certain arguments, and gives back certain results. If I follow that
   strictly, then creating the model is fairly straightforward -- and
   using it from the controller is usually a matter of only a line or
   two of code. And if you do it right, your API can accept a DB handle
   as an argument to instantiation, and simply doesn't care about such
   things as session information or CGI query parameters -- they fall
   outside its scope. That's the domain of the controller.

2. The book, "The Pragmatic Programmer," introduced me to the concept of
   domain languages. If you haven't read the book, do; it has definitely
   changed some aspects of how I program. Among other things, it has
   several nice discussions about code reuse and orthagonality that I've
   found indispensable. I actually learned a lot about MVC from it, too.
   One thing I think about often is, 'what is the domain of this piece
   of code?' PP talks about domain languages as language sub/supersets
   specific to the task, or 'domain', but one other way of thinking
   about them is what task or tasks are specific to the domain at hand.
   
   So, if I'm working on the API and find myself worrying about
   validation of parameters, I stop; validation is the domain of the
   controller. If I find myself in the view (i.e., editing a template)
   and find myself worrying about what session variables might be set
   and how to get at them... I instead request them from the controller.
   Similarlly, if I'm working in my controller (a CGI::Application
   class), and want to pull something directly from the database...
   again, I stop, and I add a new method to my API for that action.

3. Code reuse, particularly in different ways. If I have a nice, clean
   API developed, I can use it in a variety of ways, not just from my
   web-based controller. For instance, if I've created an event
   calendar, and have an API that covers adding, updating, listing,
   retrieving, and searching events, I could create scripts/libraries
   that access that same API via a command line interface, email, a GUI,
   etc. If any of it were dependent on web-specific items -- a session,
   or a CGI parameter -- it wouldn't work.

<snip>
> 2. Re-process the CGI object everywhere.  
> 
> I was optimizing some code that used this construct a lot:
> 
>  my %FORM = $self->query->Vars;
> 
> Instead of passing around the CGI query parameters I needed, I just
> relied on having the query object handy, and re-created a convenient
> hash of the query parameters. It turns out this is an expensive
> operation in CGI.pm, and it was a primary source of slowness in my code. 
> 
> As one routine called another, each was re-processing the CGI params,
> so that some lower level CGI.pm functions were being called thousands of
> times for a single request. Oops!

I've fallen down that trap as well. I now typically grab all the
parameters I'll be processing and throw them into a param() -- that way
I can utilize them from anywhere without making successive calls to the
CGI.pm object.

-- 
Matthew Weier O'Phinney
[EMAIL PROTECTED]
http://weierophinney.net/

---------------------------------------------------------------------
Web Archive:  http://www.mail-archive.com/[EMAIL PROTECTED]/
              http://marc.theaimsgroup.com/?l=cgiapp&r=1&w=2
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to