德米特定律和返回值

发布于 2024-09-05 11:29:46 字数 421 浏览 5 评论 0原文

根据Demeter法则,你可以在返回的对象上调用方法吗?

例如

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

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

According to the Law of Demeter, can you call methods on returned objects?

E.g.

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

$http->get() returns an object. Does this count as an object created/instantiated within M? If you can not call methods on it (according to LoD), how would you handle this situation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

对你而言 2024-09-12 11:29:46

这并不违反德米特法则,给出

更正式地说,迪米特定律
函数要求方法 M 为
对象 O 只能调用
方法有以下几种
对象:

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

由于 $response 是在 M 内创建的对象,因此您可以调用该对象上的方法无违规。但是,访问 getBody() 之外的属性将构成违规:

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

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

This is not a violation of the Law of Demeter, given:

More formally, the Law of Demeter for
functions requires that a method M of
an object O may only invoke the
methods of the following kinds of
objects:

  • O itself
  • M's parameters
  • any objects created/instantiated within M
  • O's direct component objects
  • a global variable, accessible by O, in the scope of M

Since $response is an object that is created within M, you can invoke a method upon that object without violation. However, it would be a violation to access properties beyond getBody():

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

Sometimes you can say that the law can be simplified by saying it's the "one dot" rule, meaning that you can access one property or method deep.

左耳近心 2024-09-12 11:29:46

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

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

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

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

On the one hand, $response appears to have been created within method m, so the answer would appear to be yes.

On the other hand, since $http has been passed in to m, the object returned by $http->get() that is now represented by $response might be a member of $http that might have been created prior to entry to m.

Considering the "only one dot" (or, in this case arrow) interpretation of the Law, rewriting the body of your function as return $http->get('http://www.google.com')->getBody(); suggests that it might be a violation. Saving the intermediate members as local variables seems like a dodgy way to avoid the one-dot principle.

I can't give a definitive answer. To some extent, I think it depends on how much you trust the $http->get() to give you a newly created object rather than a pre-existing member.

最丧也最甜 2024-09-12 11:29:46

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

One possibility to solve this is to create the object within m(), and let http->get() fill it with information.

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.
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文