我见过很多次Zend Framework使用return $this;
模式样式-从我的角度来看:
-
Pro:似乎它的
模式风格还不错,可以链接同一对象上的许多操作,缩短代码。 -
Con:当你看到对象在方法中返回自己时,代码看起来有点奇怪,方法做了其他事情(例如,某些属性的setter)
这真的很好的模式练习,或者可能是反
编辑:好吧,对我来说,称之为"模式"有点太过分了,感谢大家为我指明了正确的方向!
返回this
可以链接调用并设置值。它对于配置某些对象非常有用(请参见Fluent界面)。你可以很容易地表达你想要什么(你可以使用不同的返回类型来实现你想要的)。
我发现方法链接在有意义的情况下很有用;特定领域的语言,例如:
$query->select('*')->from('users')->where(array('user_id' => 1, 'verified' => 1));
问题是,这些方法无论如何都只会返回void
,因此return $this
只起到书写的短手版本的作用:
$query->select('*'); $query->from('users'); $query->where(...);
我们仍将调用toSQL()
或execute()
方法来利用我们填充对象的数据。
在我看来,它是而不是一种反模式,在适当的情况下可以作为一种合法、合理的对象群体方法。
如果你的意思是"好的做法还是坏的做法",我的看法是:
从好的方面来说,你会得到一些句法上的糖。
不利的一面是,您放弃了有意义的返回值,转而支持可链接性。这是不可行的,因为最终你将不得不有返回基本对象以外的东西的方法,所以你最终会得到一些可链接的方法和一些不可链接的(你的类的用户可以很有趣地猜测哪些是哪个。)
或者,不管怎样,你都全力以赴,让它们都可以链接,但随后你发现自己陷入了荒谬的境地,比如为了保存链而返回一个假的"空"对象,需要测试哪个对象的一些模糊属性,以确定它是"真的"对象还是只是链中的一个链接。
经典的例子是jQuery,它展示了所有的症状:基本对象试图成为整个代码中唯一的基本数据单元(所有东西都返回一个jQuery对象);伪对象测试(if (obj.length)
);再加上它仍然需要打破像getAttribute()
这样返回字符串的方法的可链接性的自相矛盾。
IMHO,仅仅为了那一点语法糖而把事情搞得一团糟。
这被称为Fluent接口,我不认为这是一种模式,而是一种更好的实现函数的方式,以减少代码量并提高可读性。
我让你阅读维基百科页面:http://en.wikipedia.org/wiki/Fluent_interface
这并不是PHP/ZendFramework独有的功能,因为还有许多其他编程语言使用fluent接口。我当然认为它派上了用场,使用流畅的界面是一种很好的编码方式。虽然有时候代码看起来很奇怪,但这并不意味着它是错误的,老实说,我认为你不能把它放在骗局之下。
最后,程序员只看到他得到了相同的对象,而不是它在fluent接口类的代码中的外观。我认为流畅界面中最大的优点是代码的可读性。如果你想听到一个骗局,那么调试一个流畅的链就是其中之一。
- Fluent界面