1

I am rather new to the concepts of design patterns and I'm thinking of using Dependency Injection and Polymorphism (as each are applicable) -- but I have many Singletons and while most of them can easily be changed, my DBAL cannot.

The reason why is the DBAL creates a connection to the Database -- sets up it's own PDO object. If I passed new DBALs to every class that needs it (quite a few) I would get multiple, unnecessary connections to the database.

The class is something like this

class DB { /** * Hold the PDO object * @var PDO */ private $_db; /** * Hold the last error messages * @var string */ private $_error_message = NULL; /** * Hold the last error code * @var int */ private $_error_code = NULL; /** * Connects to the database server and selects a database * * @param string $user MySQL database user * @param string $password MySQL database password * @param string $name MySQL database name * @param string $host MySQL database host * @return bool */ public function connect( $user, $password, $name, $host ) { // Connect try { $this->_db = new PDO( "mysql:host=$host;dbname=$name", $user, $password ); } catch ( PDOException $e ) { $this->_error_message = $e->getMessage(); $this->_error_code = $e->getCode(); return false; } return true; } // ... } ?> 

There will be many classes that inherit this class -- what is the best way to handle this? (I am new to design patterns)

4
  • 1
    A factory pattern should take care of injecting it in objects at instantiation (seperate instantiation / building object trees from business logic, rule of thumb if there is no 'inline' new except for in clear factories). Commented Jul 4, 2012 at 17:40
  • @Wrikken -- that makes sense to me in theory, just not entirely sure how I would go about doing it, could you give me an example of the factory method? Is the factory called statically? Or is the factory a singleton? Commented Jul 4, 2012 at 17:48
  • 1
    Ideally, from a testing point of view, you probably want instance methods, but it is hard not to fall into the trap of making everything accessible through that instance, making in essence everything global. I could very well live with 'main' objects created statically, but at a point, the Factory (or a specific subfactory) itself is something you also inject into your objects. This becomes abstract very quickly :P Commented Jul 4, 2012 at 18:14
  • @ Wrikken -- do you have a code example? A bit much for me to wrap my head around :) Commented Jul 4, 2012 at 20:26

2 Answers 2

2

An alternative method is to use a registry:

$db = new DB($host, $user, $pass); Config::set('db', $db); // Inside other classes Config::get($this, 'db'); // Passes $this so the config can override the DB for different classes 

Problem here is you end up with a Config singleton.

To truly do DI, you basicly need to pass object around to every other object.

$db = new DB($host, $user, $pass); $user = new User($db); // Or with a DI container $c = new Pimple(); $c['db'] = function() { return new DB($host, $user, $pass); }; 

But ask yourself why you don't want to use a singleton.

If it looks like a singleton, smells like a singleton, and you use it like a singleton, then a singleton pattern is probably the best fit for the job.

http://pimple.sensiolabs.org/

Sign up to request clarification or add additional context in comments.

Comments

1

add to the class:

private function __construct($user, $password, $name, $host ){ connect( $user, $password, $name, $host ); } public static function getInstance(){ if(self::$_db == NULL) self::$_db = new DB; return self::$_db; } 

and change the following:

// change $_db to be static! private static $_db = NULL; 

3 Comments

That would be a singleton, wouldn't it? My point is to get it away from being a singleton
That wasn't what I understood from your question. First - the code that you showed is not a Singleton without adding my code to it. And second, you described that you want a Singleton functionality - so why not use a Singleton ?
The title says "Replace This Singleton", I also indicated there was more code in the class, and I talk about changing singletons, but having trouble with changing my DBAL. Your answer is perfect if I wanted a singleton.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.