【问题标题】:Law of Demeter and return values得墨忒耳定律和返回值
【发布时间】:2010-06-09 13:55:23
【问题描述】:

根据Law of Demeter,你能在返回的对象上调用方法吗?

例如

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

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

【问题讨论】:

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


    【解决方案1】:

    这并不违反得墨忒耳法则,given

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

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

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

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

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

    【讨论】:

    • 除了 PHP 中的点运算符是用于连接字符串的。 :-) 我认为在最后一个.length 位有点脑残。
    • 调用(像getter)
    【解决方案2】:

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

    另一方面,由于$http 已传递给m,由$http-&gt;get() 返回的现在由$response 表示的对象可能是之前可能已创建的$http 的成员进入m

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

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

    【讨论】:

      【解决方案3】:

      解决这个问题的一种方法是在 m() 中创建对象,并让 http->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.
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多