`return $this;` design pattern or anti-pattern?

2019-02-21 13:37发布

问题:

I've seen many times Zend Framework using return $this; pattern style - and from my point of view:

  • Pro: seems its quite not bad pattern style for chaining many actions on the same object and making your code shorter.

  • Con: code looks a bit weird when you see that object returns itself in the method, which does something else (e.g. setter for some property)

Is it really good pattern practice or maybe an anti-patternpractice?

EDIT: well it was a little too much from my side to call it "pattern", thanks everyone for pointing me to right direction!

回答1:

Returning this allows you to chain calls and set values. It is very useful for configuring some object (see Fluent interface). You can express very easily what you want (and you can use different return types to achieve what you want).



回答2:

I've found method chaining to be useful in circumstances where it makes sense; a domain specific language, for example:

$query->select('*')->from('users')->where(array('user_id' => 1, 'verified' => 1));

The thing is, these methods would only be returning void anyway and so the return $this merely functions as a short hand version of writing:

$query->select('*'); $query->from('users'); $query->where(...);

We're still going to be calling the toSQL() or execute() method to make use of the data we've populated our object with.

In my opinion it is not an anti-pattern and can function as a legitimate, sensible, method of object population in the right circumstances.



回答3:

If you mean "good practice or bad practice", here's my take:

On the plus side, you get some syntactic sugar.

On the down side, you give up meaningful return values in favor of chainability. Which is not really feasible because eventually you will have to have methods which return something other than the base object, so you end up with some methods which are chainable and some which are not (users of your classes get to have fun guessing which ones are which.)

Or you go full hog and make all of them chainable no matter what, but then you find yourself in ridiculous situations such as returning a fake "empty" object for the sake of preserving the chain, which object needs to be tested for some obscure property to determine if it's a "real" one or just a link in the chain.

The classical example is jQuery, which exhibits all the symptoms: the base object attempts to be the sole basic unit of data throughout the code (everything returns a jQuery object); fake object testing (if (obj.length)); plus the self-contradiction where it still needs to break chainability for methods like getAttribute() that return string.

IMHO, it's an awful mess to make of things just for the sake of that bit of syntactic sugar.



回答4:

It is not exclusively PHP/Zend Framework doing this, as there are many other programming languages that use the fluent interface. I certainly think it comes in handy and that using the fluent interface is a good way of coding. Although sometimes codes looks weird, doesn't mean it is wrong and I don't think you can place this under con to be honest.

In the end the programmer only sees that he gets the same object back, not how it looks inside the code of the fluent interface class. I think the biggest pro in the fluent interface is the readability of the code. If you want to hear a con then debugging a fluent chain is one.

  • Fluent interface


回答5:

This is called Fluent Interface, i don't think this is a pattern but better a way to implements function to reduce amount of code and improve readibility.

I let you read the Wikipedia Page : http://en.wikipedia.org/wiki/Fluent_interface