Laravel - 静态方法和静态 instance() 方法的区别

Laravel - Diference betwen static methods and static instance() method

我在许多 Laravel 应用程序中看到这种做法,但我不知道使用它的原因有何不同。

许多人没有在 class 中使用 public 静态方法,而是只编写一个静态函数来检索 class 的实例,此实例调用该函数。

这个 classes 没有任何属性或使功能工作所需的任何东西,所以我不明白为什么要使用这种方式工作。我认为在很多情况下,这会使代码更难阅读。

例如,我看到这个 laravel 实现:

class MyClass
{
    public static function instance()
    {
        return new MyClass();
    }

    public function myStuff()
    {
        //my stuff
    }
}

//Calling it
MyClass::instance()->myStuff();

我认为它会更具可读性和相同的结果,使它与静态函数一起使用,例如:

class MyClass
{    
    public static function myStuff()
    {
        //my stuff
    }
}

//Calling it
MyClass::myStuff();

你怎么看这个?

我们知道您的担忧。很难讨论什么更好,这取决于你的项目、你的风格、你的业务。但是我们可以给你一个关键字来阅读更多相关信息:Singleton Pattern

在使用链式可选方法的情况下,为 class 提供构造函数非常有意义,然后将方法作为 non-static 和 self-returning。

class Burger
{
    private Collection $ingredients;
    
    public static function instance()
    {
        $burger = new self;
        $burger->ingredients = collect([]);
        return $burger;
    }

    public function addCheese() : self
    {
        $this->ingredients->push('cheese');
        return $this;
    }
    
    public function addMeat() : self
    {
        $this->ingredients->push('meat');
        return $this;
    }
}

$burger = Burger::instance()
    ->addCheese()
    ->addMeat()
    ->addCheese();

Laravel 中的许多 class 使用此模式,包括 Eloquent 个模型。

$posts = Post::query()
    ->where('author_id', 2)
    ->whereHas('tag', fn($tag) => $tag->where('name', 'games')
    ->get();

可以使用传统的构造函数来代替静态方法,但是您必须使用关键字 new 和括号来实例化它,这看起来不太好:

$burger = (new Burger)
    ->addCheese()
    ->addMeat()
    ->addCheese();

如果 class 只有构造函数和一个其他方法,可能是为了让 class by mocking it 将来的自动化测试变得更容易。