[Catalyst] Usage of Catalyst::Plugin::Singleton

Brandon Black blblack at gmail.com
Mon Jan 23 21:52:51 CET 2006


On 1/23/06, Alex Kavanagh <alex at tinwood.homelinux.org> wrote:
> May I ask:
>
> 1. What was the design decision behind not having a 'global' application
>    object that you could just access?  Is it a threading issue, or
>    something else?  i.e. the Singleton would effectively be breaking
>    that design decision.
>

Singleton does effectively break an otherwise good design decision,
IMHO.  But if you need a quick hack, and are willing to live with
breaking from good design decisions, it can be useful.  For any given
case where Singleton looks like a good idea, there's probably a better
solution without using Singleton (or MyApp->context, which is
similar), but it might be more difficult to design correctly.

> 2. Rightly or wrongly (probably wrongly) I'm calling functions in
>    other table classes in the DBIC model and I find I need to do this:
>
> $c->model('ModelClass')->table('some other table')->function(params)
>
>    but I don't have a $c unless I pass it around all over the place.
>    So I wrote some nasty code in the model base class to inject a
>    function called __dbic into the model table classes that simple
>    return the model base class.  Thus I can do
>
>    __dbic->table('some other table')->function(params)
>
> Is this crappy design on my part?
>

Catalyst doesn't technically know about the structure of the guts of
your model class(es), and in turn your model class(es) shouldn't know
anything about Catalyst.  I would suggest that you find a different
way to call into methods of the second table from the first table
without invoking $c->model(), using whatever methods you would use if
you were using this model from outside of Catalyst.

Or another way to think of it, is that your Model class and related
subclass should be a viable thing to use from outside of Catalyst if
designed well.  You might want to write a cron-job script that uses
your Model classes to do some table maintenance, for example.

But in any case, having a method in one table class invoke a method in
another table class smells like a design problem somewhere.  Possibly
one that could be handled with proper relationships?  If there's a
referential link between the two tables, you can let DBIC
relationship-handling take care retreiving data from the other table
class.

Or if it's more the case of a meta-function of sorts which
functionally belongs in Model code, but needs to access/manipulate
multiple tables directly (and couldn't be expressed in the database
itself with a View or something), you might consider putting this
meta-function as a method in your top-level DB/Schema class, from
where it can get at multiple tables via $self->class('TableOne'), or
$self->resultset('TableOne');

-- Brandon



More information about the Catalyst mailing list