Закон Деметры и возвращаемые значения - PullRequest
5 голосов
/ 09 июня 2010

Согласно закону Деметры , вы можете вызывать методы для возвращаемых объектов?

* 1005 Е.Г. *

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

$ http-> get () возвращает объект. Считается ли это объектом, созданным / созданным в M? Если вы не можете вызывать методы для него (согласно LoD), как бы вы справились с этой ситуацией?

Ответы [ 3 ]

6 голосов
/ 09 июня 2010

С одной стороны, $response, кажется, был создан в методе m, поэтому ответ будет да.

С другой стороны, поскольку $http было передано m, объект, возвращаемый $http->get(), который теперь представлен $response, может быть членом $http, который мог быть создан ранее для входа в m.

Учитывая «только одну точку» (или, в данном случае, стрелку) интерпретацию Закона, переписав тело вашей функции как return $http->get('http://www.google.com')->getBody();, можно предположить, что это может быть нарушением. Сохранение промежуточных членов в качестве локальных переменных кажется хитрым способом избежать принципа одной точки.

Я не могу дать однозначного ответа. В некоторой степени, я думаю, это зависит от того, насколько вы доверяете $http->get(), чтобы дать вам вновь созданный объект, а не ранее существовавший элемент.

6 голосов
/ 09 июня 2010

Это не нарушение закона Деметры, дано :

Более формально, закон Деметры для функции требует, чтобы метод М объект O может вызывать только методы следующих видов объекты:

  • О себе
  • Параметры М
  • любые объекты, созданные / созданные в M
  • Объекты прямого компонента O
  • глобальная переменная, доступная O, в области видимости M

Поскольку $ response является объектом, созданным в M, вы можете вызывать метод для этого объекта без нарушения. Однако было бы нарушением доступа к свойствам за пределами getBody():

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

Иногда вы можете сказать, что закон можно упростить, сказав, что это правило «одной точки», то есть вы можете получить доступ к одному свойству или методу.

1 голос
/ 09 июня 2010

Одна из возможностей решить эту проблему - создать объект в 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.
    }
}
...