从静态方法中创建类实例

2022-08-30 11:09:03

正如标题所说,我想从同一类的静态方法中创建一个类的实例。到目前为止,我已经发现,我可以通过做这样的事情:

class Foo{

 public $val;

 public static function bar($val){
  $inst = new Foo;
  $inst->val = $val;
  return $inst;
 }

}

因此,这让我可以做到这一点。

$obj = Foo::bar("some variable");

这很棒。

所以现在的问题是。有没有一种我不知道的更简单的方法,或者任何实现相同结果的捷径?以这种方式创建实例是否有任何优点或缺点?

谢谢。


答案 1

他们的方式很好。还有其他一些事情可以让你的生活更轻松,你也可以做。

  1. 不要对类名进行硬编码。如果您使用的是 5.3+,请使用关键字 static。这样,如果扩展该类,则新函数也可以实例化该类:

    public static function bar($var) {
        $obj = new static();
        $obj->var = $var;
        return $obj;
    }
    

    然后,您可以在任何扩展类中使用它,而无需重写任何内容。

  2. 弄清楚是否应该通过构造函数传入,而不是在构造后设置。如果对象依赖于它,则应需要它。$var

    public function __construct($var) {
        $this->var = $var;
    }
    

    这样,如果不设置变量,就无法实例化对象。

  3. 通过静态方法强制实施类的实例化。如果你正在其中执行任何需要执行的操作,请将构造函数设置为受保护或私有。这样,某人就无法绕过静态方法。

    protected function __construct() {}
    private function __construct() {}
    

我希望这有帮助...

编辑:根据您上面的评论,在我看来,您似乎在尝试实现单例设计模式。关于为什么这不是一个好主意以及它可能做的坏事,有大量的信息。它也有用途。

但是还有其他一些模式可能对你有用,这取决于你到底在做什么。

  • 如果您尝试使用相同的步骤创建不同的对象,则可以使用工厂方法
  • 如果所有对象开始时都相同,然后进行了自定义,则可以使用原型模式
  • 如果创建对象的成本特别高,则可以使用对象

但是需要考虑的一件事是,在PHP中,对象的重量非常轻。不要试图避免仅仅为了这个开销而创建新对象。避免多次执行数据库查询或文件系统访问等繁重操作。但是不要担心调用,除非 的构造函数特别重...new Foo()foo


答案 2

这看起来像一个简单的工厂方法模式。

你有一个很好的优势:假设将来你想开始使用不同的实现(但这做同样的事情)。使用工厂,只需更改创建者方法,即可更改在复杂系统的许多位置创建的所有对象。请注意,如果您使用外部类,这将更容易工作(如下面的第一个链接所示)。

保持原样,还可以对此类进行子类化并重写该方法来创建更复杂的对象。我不认为这是你想要在这里实现的。

无论如何,这对于实现测试驱动开发,抽象和许多其他好东西是很好的。

链接:

  1. Php 模式
  2. 维基百科上的工厂方法模式

推荐