Reputation: 75629
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?
Upvotes: 5
Views: 562
Reputation: 3156
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.
Upvotes: 6
Reputation: 75629
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.
}
}
Upvotes: 1
Reputation: 6956
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.
Upvotes: 6