我目前有多个类都依赖于一个类,即数据库类。每个类都需要一个 Database 类的实例才能运行,对此我有点担心。
在将所有程序代码转换为面向对象的代码之前,我需要弄清楚这一点。我目前有一个用于整个程序的数据库连接。但是,据我了解,当我将代码转换为 OOP 时,我将在同一个程序中拥有多个具有开放数据库连接的类。(所有这些类都将包含在主程序文件中)。
我该如何正确实施?我假设在同一个程序中有 5 个打开的数据库连接肯定不是正确的方法。
如果您有依赖于数据库抽象的类,那么依赖注入就是要走的路。
class PDOProvider extends PDO
{
public function __construct()
{
try {
parent::__construct(...);
$this->setAttribute(....);
} catch(PDOException $e){
die($e->getMessage());
}
}
// ...
}
class Users
{
private $provider;
public function __construct(PDOProvider $provider) // <- Injecting class dependency
{
$this->provider = $provider;
}
public function insert(array $stuff)
{
try {
$this->provider->prepare("INSERT ...");
$this->provider->execute(array(..));
} catch(PDOException $e){
//...
}
}
}
您可以通过将数据库连接作为参数提供给构造函数来在几个不同的对象之间共享数据库连接,或者您可以创建一个单例来为其他类提供数据库连接。
将数据库连接传递给构造函数
class Foo {
private $database = null;
public function __construct(&$database) {
$this->database = $database;
}
}
$connection = mysql_connect(..);
$bar = new Foo($connection);
辛格尔顿
class DatabaseConnection {
private static $instance = null;
private function __construct() {
}
public static function &getInstance() {
if (DatabaseConnection::$instance == null) {
DatabaseConnection::$instance = new DatabaseConnection();
}
return DatabaseConnection::$instance;
}
}
$mysql_query("...", DatabaseConnection::getInstance());
& 表示通过引用传递,因此即使数据库对象在多个不同的文件、类或函数中使用,也只有一个实例。有关详细信息,请参阅http://php.net/manual/en/language.references.pass.php。
Jakobs 关于使用 Singleton + 聚合的建议是合理的建议。为此,我将添加 Doctrine ORM/DBAL,http ://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/getting-started.html
通过在“Foo”类中使用它们来避免将单例实例直接耦合到您的对象,而是将单例实例传递给构造函数。这样你就有更多的脱钩,从而有更多的自由。