I am seeing this practice in many Laravel applications, and I don't know the diferences o the reasons to use this.
Instead of having public static methods in the class, many people code only one static function that retrieves an instance of a class an this instace call the function.
This classes have no properties or anything that is needed to make the functions work, so I do not understand why use this way to work. I think this make code more dificult to read, in many cases.
Example, I see this laravel implementantion:
class MyClass
{
public static function instance()
{
return new MyClass();
}
public function myStuff()
{
//my stuff
}
}
//Calling it
MyClass::instance()->myStuff();
I think it would be more readable and same result making all it with static functions, like:
class MyClass
{
public static function myStuff()
{
//my stuff
}
}
//Calling it
MyClass::myStuff();
What do you think about this?
CodePudding user response:
We know about your concern. It is difficult to discuss what is better, depend your project, your style, your business. But we can give you a keyword to read more about that: Singleton Pattern
CodePudding user response:
In cases with chained, optional methods, it makes a lot of sense to have a constructor for the class, then have the methods as non-static and 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();
Many classes in Laravel use this pattern, including Eloquent Models.
$posts = Post::query()
->where('author_id', 2)
->whereHas('tag', fn($tag) => $tag->where('name', 'games')
->get();
A traditional constructor may be used instead of a static method, but then you would have to instantiate it using the keyword new
and parentheses, which doesn't look as good:
$burger = (new Burger)
->addCheese()
->addMeat()
->addCheese();
If the class has only the constructor and one other method, possibly it was an attempt to make it easier to automate testing for the class by mocking it in the future.