我知道这是旧的,但 Dr8k 的答案几乎就在那里。
当您考虑编写一段代码时,假设它会发生变化。这并不意味着你假设它会在未来的某个时候对其进行更改,而是会进行某种形式的更改。
把它作为一个目标来减轻未来做出改变的痛苦:一个全局是危险的,因为它很难在一个地方进行管理。如果我想在将来让数据库连接上下文感知怎么办?如果我希望它在每 5 次使用时关闭并重新打开怎么办。如果我决定为了扩展我的应用程序我想使用一个包含 10 个连接的池怎么办?还是可配置的连接数?
单例工厂为您提供了这种灵活性。我以很少的额外复杂性进行设置,并且获得的不仅仅是访问相同的连接;我获得了稍后以简单的方式更改该连接传递给我的方式的能力。
请注意,我说的是单例工厂,而不是简单的单例。单例和全局之间几乎没有什么区别,真的。正因为如此,没有理由建立一个单例连接:当你可以创建一个常规的全局变量时,为什么还要花时间设置它呢?
工厂为您提供的是为什么要获得联系,以及一个单独的位置来决定您将获得哪些联系(或联系)。
例子
class ConnectionFactory
{
private static $factory;
private $db;
public static function getFactory()
{
if (!self::$factory)
self::$factory = new ConnectionFactory(...);
return self::$factory;
}
public function getConnection() {
if (!$this->db)
$this->db = new PDO(...);
return $this->db;
}
}
function getSomething()
{
$conn = ConnectionFactory::getFactory()->getConnection();
.
.
.
}
然后,在 6 个月内,当您的应用程序非常有名并被挖走并被 slashdotted 时,您决定需要多个连接,您所要做的就是在 getConnection() 方法中实现一些池化。或者,如果您决定想要一个实现 SQL 日志记录的包装器,您可以传递一个 PDO 子类。或者,如果您决定在每次调用时都需要一个新连接,您可以这样做。它是灵活的,而不是刚性的。
16 行代码,包括大括号,这将为您节省数小时和数小时的重构时间。
请注意,我不考虑这种“功能蔓延”,因为我在第一轮中没有做任何功能实现。这是“Future Creep”的边界线,但在某些时候,“为今天的明天编码”总是一件坏事的想法对我来说并不适用。