2

今天我有一个非常奇怪的类结构的 PHP 项目。像这样:

db_base
  `-- db_base_ext extends db_base
        +-- module_1 extends db_base_ext
        +-- module_2 extends db_base_ext
        .   ...
        +-- module_N extends db_base_ext
        `-- db_user extends db_base_ext

class_1
  `-- submodule_1_1 extends class_1

db_base连接到 db in __construct()并有一些辅助方法。

执行示例:

$db = new db_user();
$user = new user($db);
unset($db);

$db = new module_2();

我不喜欢在这段代码中我们两次连接到 DB 并且整个类结构不是很好。

我怎样才能让它变得更好?我的意思是只创建一个数据库实例,然后使用任何类(对应于数据库)?

单例模式对此有好处吗?

4

3 回答 3

4

你的问题是,你的结构,

module_2 extends db_base_ext
db_user extends db_base_ext
submodule_1_1 extends class_1

他们都打破了单一责任原则和里氏替换原则

我怎样才能让它变得更好。我的意思是只创建一个数据库实例,然后使用任何类(对应于数据库),可能吗?

依赖注入是要走的路。您将实例化一个数据库实例,并且您的所有类将共享同一个 $db实例。

final class MySQLPDO extends PDO
{
    public function __construct(array $params)
    {
      parent::__construct(sprintf('mysql: host=%s; dbname=%s', $params['host'], $params['database']), $params['username'], $params['password']);

      $this->setAttribute(parent::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES UTF8');
      $this->setAttribute(parent::ATTR_ERRMODE, parent::ERRMODE_EXCEPTION);
      $this->setAttribute(parent::ATTR_EMULATE_PREPARES, false);
      $this->setAttribute(parent::ATTR_DEFAULT_FETCH_MODE, parent::FETCH_ASSOC);

    }
}

$db = new MySQLPDO(array(
     'host'     => 'localhost',
     'database' => 'foo',
     'username' => 'root',
     'password' => '',
));
$user = new User($db);

$module = new Module1($user);
$foo = new Foo($db);

那么,你会在这里得到什么?重用能力和测试能力。


请注意,您应该避免使用 Singleton,因为它们引入了另一种形式的全局状态,这不利于单元测试。

于 2013-08-04T12:44:33.793 回答
2

使用正确的类名

首先,我注意到项目中的类被命名为函数。如果项目尝试使用 PEAR 命名约定,它应该做对。

使模块独立于数据库类

您应该断开模块与db_base_ext课程的连接。如果模块需要访问数据库实例,可以使用构造函数参数或设置器来提供。它不应该直接扩展类。

$module = new Module($database);
于 2013-08-04T11:12:56.810 回答
-2

您应该考虑为您的 DB 类使用单例模式。

看看这里的教程。它使用 PDO 进行通信,但对 mysqli 或其他类型也应该有效。

于 2013-08-04T10:51:36.230 回答