Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re: OOP design related question.

by Ctrl-z (Friar)
on Sep 10, 2005 at 10:58 UTC ( [id://490868]=note: print w/replies, xml ) Need Help??


in reply to OOP design related question.

I would second the Singleton approach suggested by others - the dbh isn't really an attribute of your objects, your just stashing it to pass around. You might as well provide a global point of access for objects if and when they need it.

It would also give you a logical place to put other generic DB related code, and could be quite easily integrated with your DBIx::Handy module:

package DBIx::Handy; my $dbh = undef; sub get_instance { my $class = shift; if($dbh == undef){ $dbh = ... } return $dbh; } ...etc



time was, I could move my arms like a bird and...

Replies are listed 'Best First'.
Re^2: OOP design related question.
by techcode (Hermit) on Sep 10, 2005 at 22:06 UTC
    Don't know if you noticed but I'm not actually passing DBH. I'm passing reference to instance of DBIx::Handy actually.

    The thing that I dont understand about singleton's. I know that you can create only one at any given time - but is that sort to say system wide - or just in that process?

    I believe it's just for that process of course - but then again it raises questions what happens when you work under mod_perl or similar (threads?)

    Anyway the code that you wrote (just checking if I understood everything right) allows me to create more instances of DBIx::Handy, but only one DB connection?

    Problem is that I will need two DB connections as at one point of time, I need to read data from another DB ... One idea would be to use Memoize and since call to connect would have different parameters it would create different DBH. Then it gets even more complicated :) As to do so I need to store several DBH and somehow tell to DBIx::Handy which one to use for particular query...

    But I like your idea as it's simple...
      Anyway the code that you wrote (just checking if I understood everything right) allows me to create more instances of DBIx::Handy, but only one DB connection?

      If you want that, then $dbh is just the equivalent of a static field, shared between all DBIx::Handy objects (in a process). That may be fine, but to be a classic Singleton get_instance should conditionally create and return the sole instance of its class. The difference is more obvious in Object Oriented languages where new is more than just a naming convention. See SingletonPattern.

      The nice thing about design patterns is that they should be modified to suit your needs. In your case, I would be inclinded to have a class that manages the configuration and singleton-ness of your database handle(s). That way you avoid passing around existing objects or creating new ones that just wrap static fields. By encapsulating each database connection in a class, you can skip the need for memoization and localize changes. Bonus!

      package DBIx::Handy::Singleton; our @ISA = ('DBIx::Handy'); my %instances = (); sub new{ die "ack! Cant call new on Singleton class '$_[0]'!\n"; } sub get_instance { my $class = ref $_[0] || $_[0]; unless($instances{$class}){ my $dbh = bless DBIx::Handy->new( $class->configure() ), $clas +s; $dbh->connect(); # ...etc $instances{$class} = $dbh; } return $instances{$class}; } sub configure{ die "Unimplemented abstract method 'configure' in '$_[0]'\n"; } package MyApp::Foo; our @ISA = ('DBIx::Handy::Singleton'); sub configure{ return (driver => ..., database => ..., ...); } package MyApp::Bar; our @ISA = ('DBIx::Handy::Singleton'); sub configure{ return (driver => ..., database => ..., ...); }

      As for the mod_perl/threading issues, I dont know enough about either to comment fully, other than to say that usually access to get_instance would be limited to one thread to avoid race conditions while checking the singleton exists. Check CPAN, a quick search brought up Apache::Singleton...




      time was, I could move my arms like a bird and...
        I don't feel good with inheriting DBIx::Handy (or DBIx::Handy::Singleton as it is the same thing) as DBIx::Handy has methods named like insert, update, connect ...

        IMHO it's better to just say my $DB = DBIx::Handy->new() where I need to use it. Or probably a better solution would be having a package that is base for everything in the application and having just dbix_handy method (that would return the DBIx::Handy instance in it.

        Oh well, I'll try all of those solution and see what works best - after all, those with more experience means that they made more mistakes :)

        Either way, Design Patterns are the next thing I intend to give my attention to.

        Thanks!
Re^2: OOP design related question.
by techcode (Hermit) on Sep 10, 2005 at 22:06 UTC
    Don't know if you noticed but I'm not actually passing DBH. I'm passing reference to instance of DBIx::Handy actually.

    The thing that I dont understand about singleton's. I know that you can create only one at any given time - but is that sort to say system wide - or just in that process?

    I believe it's just for that process of course - but then again it raises questions what happens when you work under mod_perl or similar (threads?)

    Anyway the code that you wrote (just checking if I understood everything right) allows me to create more instances of DBIx::Handy, but only one DB connection?

    Problem is that I will need two DB connections as at one point of time, I need to read data from another DB ... One idea would be to use Memoize and since call to connect would have different parameters it would create different DBH. Then it gets even more complicated :) As to do so I need to store several DBH and somehow tell to DBIx::Handy which one to use for particular query...

    I like your idea as it's simple...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://490868]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (7)
As of 2024-03-28 10:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found