Pregunta

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)

¿Fue útil?

Solución

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/

Otros consejos

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;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top