根据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),你会如何处理这种情况?
答案 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.
}
}