我经常看到这些类,但我的项目中没有使用它们。我在这里检查了这些设计模式,我注意到它们使用静态类
来自上面的页面,示例代码:
class AutomobileFactory
{
public static function create($make, $model)
{
return new Automobile($make, $model);
}
}
或辛格尔顿模式:
public static function getInstance()
{
static $instance = null;
if (null === $instance) {
$instance = new static();
}
return $instance;
}
我建议您先阅读《如何使用Statics不破坏您的可测试性》,作为我将在下面讨论的内容的介绍。
工厂的目的通常是允许为需要实例化其他对象的方法/对象注入依赖项。例如:
public function foo() {
$bar = new Bar;
}
正如前面文章中所讨论的那样,这是不好的。但是此方法必须能够实例化Bar
对象本身。然而,我们仍然想要依赖注入
进入工厂:
public function foo(BarFactory $factory) {
$bar = $factory->create();
}
因此,static
工厂是毫无意义的:
public function foo() {
$bar = BarFactory::create();
}
在这里几乎没有直接实例化new Bar
的优势。
单身汉是一个热门话题,他们经常被劝阻,原因与全局对象被劝阻的原因相同。静态引用的奇点又是坏的,正如文章中详细讨论的那样。
第一个例子是一个工厂类。工厂是一段帮助您创建和配置对象的代码。工厂可以是函数或方法、静态类或实例化类。通常不需要实例化工厂,因此通常使用静态类。但我认为工厂也可以实例化。这样做可以配置或扩展工厂,从而使您比使用单个静态工厂方法更具灵活性。
此外,我认为在大多数情况下,静态类只是一个借口。人们通常倾向于将全局函数或变量提升到静态类中,以生成"干净"的代码,但这并没有带来什么改进。在PHP支持名称空间之前,它有点有用,但现在,我认为在创建静态类时应该小心。
这同样适用于singleton,尽管它有它的用途,因为在某些情况下,你只想拥有一个类的实例。这方面的例子包括连接池或硬件控制器。拥有某个对象的多个实例可能会导致问题,所以这是使用singleton的一个很好的理由。但是,当不需要的时候,人们通常会将一个对象设置为singleton。在这种情况下,我认为这只是一种掩盖你使用全局变量的方式,这是一种糟糕的做法。
但是singleton并不是一个静态类。它只是一个隐藏构造函数的类,并提供一个静态方法来访问该类的单个实例。它与静态类相似,但不同。
我可以推荐阅读"头部优先设计模式"。它以一种有趣且易于理解的方式解释了这两种模式(以及更多)。代码示例倾向于Java,但这几乎不是问题。
这些类有明确的用途。让我们举一个记录器的例子。
class Logger() {
private __construct() {}
public static function getInstance()
{
static $instance = null;
if (null === $instance) {
$instance = new static();
}
return $instance;
}
//other methods here
}
}
现在,在实例化它一次之后,你可以做一些类似的事情
Logger::log(parameters)
其中CCD_ 4是该类中的方法。
这只是这样一个类非常有用的例子。