[RESOLVED] Factory Pattern w/ database conn

liunx

Guest
What I am trying to do is centralise all my database stuff into one place.

the end result I am looking for is something like;



$user = db::getUserByID($ID);



So the db object will retrieve the data and return the results as the right type of object.

I can understand how to do it all pretty well. The query, putting it into objects and so on. that's fine.

However, how can i make it use only one database connection? since with the factory method there isn't an instance, I'm confused.It's quite common to implement the database connection as a singleton, which is essentially a static property in a class with a method which instantiates and/or returns the object depending on whether it has previously been instantiated. The downside is you end up having to make static calls to get at the database, which leads to a strong coupling between the two classes, and is just not very 'OO'.

The alternative is just to pass the connection to the method which needs it as a parameter. This might even be preferable as it removes the dependency between the class containing the getUserByID() method and the database connection. This can be a big help when unit testing a class.

Now you might think it can be annoying having to pass lots of parameters around which various objects needed, for example database connections and configuration, so a solution is the Service Locator pattern. This is essentially an object containing a bunch of factory methods for getting at common services needed by the app. You now just need to pass the Service Locator around.

A quick code example

class UserModel
{
function __construct( $servicelocator )
{
$this->servicelocator = $servicelocator
}
function getUserById( $id )
{
$row = $this->servicelocator->getDb()->query( 'SELECT ... WHERE ' . $id );
return $this->doSomethingWithRow( $row );
}
}
class SomeSpecificDatabase
{
function query( $sql )
{
// do query
}
}
class ServiceLocator
{
private static $instances = array();
function getDb()
{
if( !isset( ServiceLocator::$instances['db'] ))
{
ServiceLocator::$instances[$db] = new SomeSpecificDatabase;
}
return ServiceLocator::$instances[$db];
}
}
$service = new ServiceLocator;
$model = new UserModel( $service );
$user = $model->findUserById( 1 );

Dependencies still exist in the Service Locator but from a testing perspective thats better than having them littered throughout your code.

Sorry for the long post ;)Thanks, long but well written and useful post!

I like the idea of the servicelocator... I might have a go at that.

Ive read about singleton a few times but to be honest I've never really understood that. I'll see if I can find any good reading on it. Do you have any recommendations?

Thanks again.<!-- m --><a class="postlink" href="http://www.phppatterns.com/docs/design/singleton_pattern">http://www.phppatterns.com/docs/design/ ... on_pattern</a><!-- m --> :)
 
Back
Top