【发布时间】:2014-07-31 03:48:55
【问题描述】:
我将开始使用 PHP 自学 OOP。
我正在创建几个小型 Web 应用程序,并遵循了很多教程,这些教程要么通过单例创建数据库(使用 PDO),要么通过传递全局。我读到这些几乎是一回事,都应该像瘟疫一样避免。
所以我观看了关于干净代码的 Google 技术讲座,并且阅读了几乎所有关于依赖注入等的 SO 文章。我有几个问题。
- 干净的代码视频建议您不要在构造函数中“工作”。这是关于业务逻辑的“工作”。 IE。如果我的班级的工作是创建另一个对象,那是一种好的“工作”吗?
例如,为了符合单一责任类,我创建了三个。
- DB 类 - 实际连接到数据库。
- DBFactory 类 - 创建连接到数据库的 DB 对象。
- 类 DBInstance - 返回 DBFactory 创建的 PDO 对象的单个实例。
请注意,我正在尝试创建单个实例,而不创建单例模式。
所以我尝试将每个类的依赖项向上传递。我发现自己必须创建所有对象(从 DB 向下),以便注入依赖项。出于某种原因,我认为它会以另一种方式工作,我会创建第一个对象,它会为我创建第二个对象等等。我显然错过了什么?
希望这对其他人也有帮助 - 似乎有无数关于这些东西和数据库的问题,但很少有好的例子。
(我应该提到这确实有效,我确实从数据库中获得了酒店名称列表!)
TestCode.php
include './classes/DB.php';
include './classes/DBFactory.php';
include './classes/DBInstance.php';
include './classes/Location.php';
$db = new DB;
$dbfactory = new DBFactory($db);
$dbinstance = new DBInstance($dbfactory);
$dbh = $dbinstance->getDbInstance();
//Example business logic
$location_names = Location::getLocationNames($dbh);
print_r($location_names);
类 DB.php:
class DB {
private $_dbhost = 'myhost';
private $_dbname = 'myname';
private $_dbuser = 'myuser';
private $_dbpass = 'mypass';
private $_error;
public function connect() {
try {
return new PDO("mysql:host=$this->_dbhost;dbname=$this->_dbname",
$this->_dbuser, $this->_dbpass);
}
catch (PDOException $e) {
$this->_error = 'Error! ' . $e->getMessage() . '<br />';
die();
}
}
public function getError() {
if (isset($this->_error)) {
return $this->_error;
}
}
}
类 DBFactory.php
class DBFactory {
private $_dbh;
public function __construct(DB $db) {
$this->_dbh = $db;
}
public function Create() {
return $this->_dbh->Connect();
}
}
类 DBInstance.php
class DBInstance {
private static $_dbinstance;
public function __construct(DBFactory $dbfactory) {
if (!isset(self::$_dbinstance)) {
self::$_dbinstance = $dbfactory->Create();
}
}
public function getDbInstance() {
return self::$_dbinstance;
}
}
【问题讨论】:
-
@félix-gagnon-grenier 我是否成功创建了单个实例,而没有创建单例模式?有没有更好的方法来创建一个新的数据库处理程序,同时仍然使用依赖注入,而不必像我在测试类中那样实例化所有对象?
标签: php oop design-patterns singleton database-connection