得墨忒耳定律和返回值

Sjo*_*erd 5 language-agnostic coupling law-of-demeter

根据Demeter法则,您可以调用返回物体的方法吗?

例如

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

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

Jef*_*her 6

这并不违反得墨忒耳法,因为:

更正式地说,函数的Demeter法则要求对象O的方法M只能调用以下类型的对象的方法:

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

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

$length = $response->getBody()->length;
Run Code Online (Sandbox Code Playgroud)

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


Pau*_*her 6

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

另一方面,由于$http已经传入,因此现在由其m返回的对象可能是在进入之前可能已创建的对象.$http->get()$response$httpm

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

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