PHP静态v单例类-ConnectionFactory解释
我是这一级别的PHP编程新手,我一直在读一篇关于单例和静态类的文章。我正在编写一个类,它将促进我的数据库连接 我遇到了Jon Raphaelson()编写的以下代码: 看起来我已经找到了我想要的东西,但是我有一些问题PHP静态v单例类-ConnectionFactory解释,php,static,singleton,Php,Static,Singleton,我是这一级别的PHP编程新手,我一直在读一篇关于单例和静态类的文章。我正在编写一个类,它将促进我的数据库连接 我遇到了Jon Raphaelson()编写的以下代码: 看起来我已经找到了我想要的东西,但是我有一些问题 self::$factory=新连接工厂(…)-我在这个类中没有看到构造函数。我是否只是创建这个构造函数并传入数据库详细信息(“dbname”、“user”、“pass”等) 函数,我假设它的目的是将所有实际的函数都放在ConnectionFactory类中检索数据,这就是这个函数
self::$factory=新连接工厂(…)代码>-我在这个类中没有看到构造函数。我是否只是创建这个构造函数并传入数据库详细信息(“dbname”、“user”、“pass”等)
谢谢 工厂是一个单独的工厂,因为您不需要多个工厂
new ClassName()
实例化。然而,如果该类被认为是一个单例(在本例中看起来是这样的),那么模式的整个要点就是使此类实例化无法从类外部进行,这就是为什么我认为应该有一个使用private
关键字声明的构造函数getSomething()
是一个“独立”函数,包含使用类的示例class ConnectionFactory {
protected static $connection;
public function getConnection() {
if (!self::$connection) {
self::$connection = new PDO(...);
}
return self::$connection;
}
}
此工厂的用户应该期望它的一个实例,而不是自己调用它:
class Foo {
protected $connectionFactory;
public function __construct(ConnectionFactory $factory) {
$this->connectionFactory = $factory;
}
public function somethingThatNeedsAConnection() {
$connection = $this->connectionFactory->getConnection();
...
}
}
$foo = new Foo(new ConnectionFactory);
这允许Foo
在需要时获得连接本身,但也允许您向Foo
注入一些替代连接,例如用于测试目的
作为一种方便的措施和降低实例化复杂性的方法,此模式也很好:
class Foo {
protected $connectionFactory;
public function __construct(ConnectionFactory $factory = null) {
if (!$factory) {
$factory = new ConnectionFactory;
}
$this->connectionFactory = $factory;
}
...
}
这仍然允许注入和重写依赖项,但它不要求每次实例化
Foo
时都注入工厂,我建议不要使用这种模式。请参阅了解原因和备选方案。@deceze您是否建议PHP用户不要使用Factory模式或Singleton模式?我不知道为什么它们本质上是坏的——它们是经过严格审查的OOP模式。@Ray我反对单例模式,更具体地说是反对静态调用ConnectionFactory::getFactory()
anywhere。如果您使用的是工厂,那么应该将该工厂作为对象注入,而不是静态调用。单件工厂是毫无意义的。工厂应该用来为对象A提供构造其他对象B的方法,而无需将A静态耦合到B。因此,将A静态耦合到工厂B没有任何好处。@deceze如何强制不创建工厂或连接的多个副本?例如,对于资源有限的事物,例如连接到数据库,您或使用代码的人可能会意外地创建比可用连接更多的连接。诚然,这是更多可测试的方法和类,但这样做也更有可能创建单元测试正常工作的情况,但当预期的连接被拒绝或由于资源争用而超时时,整个代码都会中断。@Ray将实例化的连接另存为工厂的静态
属性。您可以根据需要实例化任意多个工厂,但它们都只提供一个连接。更好的方法是,只在调用链中的某个较高位置创建一次连接,并使用依赖项注入将其传递到每个需要它的对象中。Ray,谢谢(还有#2上的oops,不确定我为什么错过了它,可能原始帖子的间距不同)。@NEW2WEB没问题,请查看我的更新。希望它能解决一切问题。
class Foo {
protected $connectionFactory;
public function __construct(ConnectionFactory $factory) {
$this->connectionFactory = $factory;
}
public function somethingThatNeedsAConnection() {
$connection = $this->connectionFactory->getConnection();
...
}
}
$foo = new Foo(new ConnectionFactory);
class Foo {
protected $connectionFactory;
public function __construct(ConnectionFactory $factory = null) {
if (!$factory) {
$factory = new ConnectionFactory;
}
$this->connectionFactory = $factory;
}
...
}