代码之家  ›  专栏  ›  技术社区  ›  Sjoerd

德米特定律与回归值

  •  5
  • Sjoerd  · 技术社区  · 14 年前

    根据 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),您将如何处理这种情况?

    3 回复  |  直到 12 年前
        1
  •  6
  •   Gordon Haim Evgi    12 年前

    这不是违反德米特的法律, given :

    更正式地说,德米特定律 函数要求 对象o只能调用 以下几种方法 物体:

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

    由于$response是在m中创建的对象,因此您可以对该对象调用方法而不违反。但是,访问超过 getBody() :

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

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

        2
  •  6
  •   Paul Butcher    14 年前

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

    另一方面,因为 $http 已传给 ,返回的对象 $http->get() 现在的代表是 美元响应 可能是 $HTTP 可能是在进入之前创建的 .

    考虑到“只有一个点”(在本例中是箭头)对法律的解释,将函数体改写为 return $http->get('http://www.google.com')->getBody(); 暗示这可能是违反规定。将中间成员保存为局部变量似乎是避免单点原理的一种不可靠的方法。

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

        3
  •  1
  •   Sjoerd    14 年前

    解决这个问题的一种方法是在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.
        }
    }