正如标题所说,我想要在同一个类的静态方法中创建一个类的实例。到目前为止,我已经想到了我可以做这样的事情:
class Foo{
public $val;
public static function bar($val){
$inst = new Foo;
$inst->val = $val;
return $inst;
}
}
因此我可以这样做。
$obj = Foo::bar("some variable");
哪个好。
所以现在问题。是否有一种更容易实现的方法,我不知道,或任何实现相同结果的捷径?以这种方式创建实例有什么优点或缺点吗?
感谢。
答案 0 :(得分:83)
他们这样做你很好。还有一些其他的东西可以让你的生活更轻松,你可以做。
不要对类名进行硬编码。如果您使用的是5.3+,请使用关键字static
。这样,如果你扩展类,新函数也可以实例化那个:
public static function bar($var) {
$obj = new static();
$obj->var = $var;
return $obj;
}
然后您可以在任何扩展类中使用它,而无需覆盖任何内容。
弄清楚$var
是否应该通过构造函数传递而不是在构造之后设置。如果对象依赖于它,你应该要求它。
public function __construct($var) {
$this->var = $var;
}
这样,如果不设置变量,就无法实例化对象。
通过静态方法实施类的实例化。如果你在那里做任何你需要做的事情,那么使构造函数保护或私有。这样,有人无法绕过静态方法。
protected function __construct() {}
private function __construct() {}
我希望有帮助...
修改:根据您上面的评论,我觉得您正在尝试实施Singleton Design Pattern。有大量的信息说明为什么它不是一个好主意和它可能做的坏事。它也有用途。
但是根据你正在做的事情,还有一些其他模式对你有用。
但有一点需要考虑的是,PHP对象的重量非常轻。不要试图避免仅为此开销创建新对象。避免多次执行数据库查询或文件系统访问等繁重操作。但是不要担心调用new Foo()
,除非foo
的构造函数特别重......
答案 1 :(得分:3)
这看起来像一个简单的工厂方法模式。
你有一个很好的优势:假设将来你想要开始使用不同的实现(但是它做同样的事情)。使用工厂,您只需更改创建者方法即可更改在复杂系统的许多位置创建的所有对象。请注意,如果您使用外部类(如下面第一个链接中所示),这将更容易。
保持现在的状态,您也可以对此类进行子类化并覆盖该方法以创建更复杂的对象。我不认为这是你想要在这里实现的目标。
无论如何,这对于启用测试驱动开发,抽象和许多其他好事都很有用。
链接:
答案 2 :(得分:0)
如果您只是创建一个对象,这不是很有用。你可以只调用一个构造函数。但是,如果你正在做一些更复杂的事情(比如你从一些单例模式开始但未包含本例中的所有细节),那么:
这听起来很对。如果要阻止以默认方式创建的对象,请执行以下操作:
$obj = new Foo("Some Variable");
您可以添加私有构造函数:
class Foo{
public $val;
private __construct(){}
public static function bar($val){
$inst = new Foo;
$inst->val = $val;
return $inst;
}
}
现在您强制人们使用您的静态类。在函数中设置val的需要可能已经消失了,所以你甚至可以将value-parameter添加到你的私有构造函数中,但是做其他事情(你可能想做的事情,比如查看某种单例模式) 'bar'功能
答案 3 :(得分:0)
超级晚,但发现这很有用。
一个很好的例子是来自Audi的UI库的静态方法,该方法从Array
的{{1}}方法中返回TextField
的实例化TextField
类{ {1}}。
static
在回购中查看其余信息 https://github.com/audi/audi-ui/blob/master/src/textfield/textfield.js#L25