静态构造函数的最佳做法

2022-08-30 17:07:19

我想创建一个类的实例,并在该实例上调用一个方法,只需一行代码。

PHP 不允许在常规构造函数上调用方法:

new Foo()->set_sth(); // Outputs an error.

所以我正在使用,如果我可以称之为,静态构造函数:

Foo::construct()->set_sth();

这是我的问题:

使用这样的静态构造函数是否被认为是一种很好的做法,如果是,您如何建议为这些静态构造函数命名方法?

我一直在犹豫以下选项:

Foo::construct();
Foo::create();
Foo::factory()
Foo::Foo();
constructor::Foo();

答案 1

正如@koen所说,静态构造函数(或“命名构造函数”)只有利于证明意图。

但是,从5.4开始,出现了一种称为“取消引用”的东西,它允许您使用方法调用直接内联类实例化。

(new MyClass($arg1))->doSomething(); // works with newer versions of php

因此,静态构造函数仅在有多种方法可以实例化对象时才有用。如果只有一个(始终是相同类型的参数和参数数),则不需要静态构造函数。

但是,如果您有多种实例化方式,那么静态构造函数非常有用,因为它可以避免用无用的参数检查来污染主构造函数,从而削弱语言约束。

例:

<?php

class Duration
{
private $start;
private $end;

// or public depending if you still want to allow direct instantiation
private function __construct($startTimeStamp = null, $endTimestamp = null)
{
   $this->start = $startTimestamp;
   $this->end   = $endTimestamp;
}

public static function fromDateTime(\DateTime $start, \DateTime $end)
{
    return new self($start->format('U'), $end->format('U'));
}

public static function oneDayStartingToday()
{
    $day = new self;
    $day->start = time();
    $day->end = (new \DateTimeImmutable)->modify('+1 day')->format('U');

    return $day;
}

}

正如您在 中看到的,静态方法可以访问实例的私有字段!疯了不是吗?:)oneDayStartingToday

有关更好的解释,请参阅 http://verraes.net/2014/06/named-constructors-in-php/


答案 2

任何方法的命名都应该有意揭示名称。我不知道'Foo::factory'是做什么的。尝试构建更高级的语言:

User::with100StartingPoints();

这将与以下内容相同:

$user = new User();
$user->setPointsTo(100);

您还可以轻松测试User::with100StartingPoints()是否等于此值。


推荐