`return $ this;`设计模式还是反模式?

时间:2011-05-26 12:51:04

标签: php oop design-patterns anti-patterns

我多次看到使用return $this; pattern 样式的Zend Framework   - 从我的观点来看:

  • Pro:似乎是非常糟糕的 pattern 样式,用于在同一个对象上链接许多操作并缩短代码。

  • Con:当你看到该对象在方法中返回时,代码看起来有点奇怪,这会做其他事情(例如某些属性的setter)

这是非常好的 pattern 练习还是反模式练习?

编辑:从我这边称它为“模式”有点太多了,谢谢大家指点我正确的方向!

5 个答案:

答案 0 :(得分:10)

返回this允许您链接调用和设置值。它对于配置某个对象非常有用(请参阅Fluent interface)。您可以非常轻松地表达您想要的内容(并且您可以使用不同的返回类型来实现您想要的目标)。

答案 1 :(得分:7)

我发现方法链在有意义的情况下很有用;特定于域的语言,例如:

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

问题是,这些方法只会返回void,所以return $this只是作为写作的简写版本:

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

我们仍然会调用toSQL()execute()方法来使用我们填充对象的数据。

在我看来,它是一种反模式,并且在适当的情况下可以作为合法,合理的对象群体方法。

答案 2 :(得分:7)

如果你的意思是“良好做法或不良做法”,这是我的看法:

从好的方面来说,你会得到一些语法糖。

在不利方面,您放弃了有意义的返回值,转而支持可链接性。这不是真的可行,因为最终你必须拥有返回基本对象以外的东西的方法,所以你最终会得到一些可链接的方法和一些不可链接的方法(你的类的用户可以有趣地猜测哪些是其中。)

或者你全力以赴,无论如何都可以将它们全部链接起来,但是你会发现自己处于荒谬的境地,例如为了保留链条而返回假的“空”对象,需要对其进行测试一些不起眼的属性,以确定它是“真正的”还是链中的链接。

经典的例子是jQuery,它展示了所有的症状:基础对象试图成为整个代码中唯一的基本数据单元(一切都返回一个jQuery对象);假对象测试(if (obj.length));再加上自相矛盾,它仍然需要打破返回字符串的getAttribute()等方法的可链接性。

恕我直言,只是为了那些语法糖而制造东西真是一团糟。

答案 3 :(得分:3)

这不仅仅是PHP / Zend Framework这样做,因为还有许多其他编程语言使用流畅的界面。我当然认为它派上用场,使用流畅的界面是一种很好的编码方式。虽然有时代码看起来很奇怪,但并不意味着它是错误的,我认为你不能把它放在一边说实话。

最后程序员只看到他得到了同样的对象,而不是它在流畅的接口类的代码中看起来如何。我认为流畅的界面中最大的专业是代码的可读性。如果你想听到con,那么调试一个流畅的链是一个。

答案 4 :(得分:2)

这称为Fluent Interface,我不认为这是一种模式,但更好的方法是实现函数以减少代码量并提高可读性。

我让你阅读维基百科页面:http://en.wikipedia.org/wiki/Fluent_interface