我想禁用一个由new
运算符实例化的类,但我们假设一个getObject
方法创建并返回它的一个实例。它可行吗?
答案 0 :(得分:4)
class C
{
protected function __construct()
{
}
public static function getObject()
{
return new self();
}
}
更新:
上面的代码满足要求:无法使用new
实例化类,需要使用工厂方法getObject()
来创建对象。但是,OP没有说明他们需要这样一个结构的原因。
出现这种设计有几个原因;其中之一就是当C
类型的对象的创建需要通过一些初始化来完成时,无论出于何种原因,都无法在类的构造函数中完成。
这种构造类C
对象的方法的另一个原因是Singleton
设计模式;实际上这是一种“反模式”,但这是另一种讨论;为了实现Singleton,类C
应如下所示:
class C
{
private static $instance = NULL;
protected function __construct()
{
}
public static function getObject()
{
if (! isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
}
Singleton
与否,因为方法getObject()
是静态的,所以测试框架不能对其进行存根或模拟,并且必须使用其原始实现。更多,因为它是创建类C
的对象的唯一方法,所以使用此类的其他类不能单独测试。
总而言之,即使是可以施工,也不建议使用。使用语言机制强制创建类C
的对象使得该类成为测试使用它的其他类的麻烦。
如果由于复杂的初始化而需要通过某种方法创建类C
的对象,则更好的方法是使用Builder
设计模式。使它成为另一个类(“构建器”)的非静态方法,并指示程序员(使用类文档)不使用C
直接创建类new
的对象。这样它不会影响其他类的可测试性。
答案 1 :(得分:3)
我想禁用由
实例化的类new
运算符
一种常见的方法是将构造函数私有化。
class Example {
private function __construct() {
}
}
以下情况会导致致命错误。
$object = new Example();
虽然这会奏效,但我鼓励您和未来的读者审核Design Patterns in PHP。