Закон Деметры и возвращаемые значения

Можно ли в соответствии с законом Деметры вызывать методы для возвращаемых объектов?

E.g.

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

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


person Sjoerd    schedule 09.06.2010    source источник


Ответы (3)


Это не нарушение Закона Деметры, с учетом:

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

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

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

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

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

person Jeff Schumacher    schedule 09.06.2010
comment
За исключением того, что оператор точки в PHP предназначен для объединения строк. :-) Я думаю, что в этом последнем .length бите было немного мозгов. - person janmoesen; 28.06.2010
comment
делает вызов (как геттер) - person nemenems; 26.03.2014

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

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

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

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

person Paul Butcher    schedule 09.06.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.
    }
}
person Sjoerd    schedule 09.06.2010