得墨忒耳定律和返回值

时间:2010-06-09 13:55:23

标签: language-agnostic coupling law-of-demeter

根据Law of Demeter,您可以在返回的对象上调用方法吗?

E.g。

<?php
class O
{
    public function m($http)
    {
        $response = $http->get('http://www.google.com');
        return $response->getBody(); // violation?
    }
}
?>

$ http-&gt; get()返回一个对象。这是否算作在M中创建/实例化的对象?如果你不能在它上面调用方法(根据LoD),你会如何处理这种情况?

3 个答案:

答案 0 :(得分:6)

这不违反得墨忒耳法given

  更正式地说,得墨忒耳的法则   函数需要一个方法M   对象O只能调用   方法有以下几种   对象:

     
      
  • O本身
  •   
  • M的参数
  •   
  • 在M
  • 中创建/实例化的任何对象   
  • O的直接组件对象
  •   
  • 一个全局变量,可由O访问,范围为M
  •   

由于$ response是在M中创建的对象,因此您可以在该对象上调用方法而不会违反。但是,访问getBody()以外的属性会违反

$length = $response->getBody()->length;

有时你可以说法律可以通过说它是“一个点”规则来简化,这意味着你可以深入访问一个属性或方法。

答案 1 :(得分:6)

一方面,$response似乎是在方法m中创建的,所以答案似乎是肯定的。

另一方面,由于$http已传入m$http->get()返回的现在由$response表示的对象可能是$http的成员{1}}可能是在输入m之前创建的。

考虑到法律的“只有一个点”(或者,在这种情况下是箭头)解释,将函数体重写为return $http->get('http://www.google.com')->getBody();表明它可能是违规行为。将中间成员保存为局部变量似乎是避免单点原则的一种狡猾的方式。

我无法给出明确的答案。在某种程度上,我认为这取决于您信任$http->get()对您提供新创建的对象而不是预先存在的成员的程度。

答案 2 :(得分:1)

解决这个问题的一种可能性是在m()中创建对象,让http-&gt; get()用信息填充它。

class O
{
    public function m($http)
    {
        $response = new HttpResponse();
        $http->get('http://www.google.com', & $response);
        return $response->getBody(); // no violation, since we made $response ourselves.
    }
}