Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

Re^3: OOP design related question.

by Ctrl-z (Friar)
on Sep 11, 2005 at 01:25 UTC ( [id://490959] : note . print w/replies, xml ) Need Help??

in reply to Re^2: OOP design related question.
in thread OOP design related question.

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

Replies are listed 'Best First'.
Re^4: OOP design related question.
by techcode (Hermit) on Sep 11, 2005 at 09:16 UTC
    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.