2010-06-09 22 views
5

Według , możesz wywołać metody na zwróconych obiektach?Prawo Demeter i wartości zwracane

E.g.

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

$ http-> get() zwraca obiekt. Czy to się liczy jako obiekt utworzony/utworzony w M? Jeśli nie możesz wywołać metod (zgodnie z LoD), jak poradzisz sobie z tą sytuacją?

Odpowiedz

6

Nie jest to sprzeczne z prawie Demetry, given:

Formalnie, prawo Demetry do funkcji wymaga to sposobie M obiekt O może wywołać tylko metody następujące rodzaje obiektów:

  • sama o
  • parametrów M
  • wszelkie obiekty utworzone/instancja ciągu M
  • bezpośredni komponent
  • O za obiekty
  • zmienną globalną, dostępną przez O, w zakresie M

Od $ odpowiedzi jest obiektem, który jest tworzony w ciągu M, możesz wywołać metodę na tym obiekcie bez naruszenia. Jednak byłoby to naruszenie właściwościom dostępu poza getBody():

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

Czasami można powiedzieć, że prawo można uprościć, mówiąc, że jest to zasada „jeden punkt”, co oznacza, że ​​można uzyskać dostęp do jednej właściwości lub metody głębokiego .

+0

Z tym, że operator kropki w PHP służy do łączenia łańcuchów. :-) Myślę, że niewielkie brzemię w tym ostatnim kawałku "długości". – janmoesen

+0

dzwoni (jak kupiec) – nemenems

6

Z jednej strony wydaje się, że $response zostało utworzone w ramach metody m, więc odpowiedź wydaje się być twierdząca.

Z drugiej strony, ponieważ $http została podjęta w celu m, obiekt zwrócony przez $http->get() który jest obecnie reprezentowany przez $response może być członkiem $http które mogły zostać utworzone przed wejściem do m.

Rozpatrując "tylko jedną kropkę" (lub w tym przypadku strzałkę) interpretację Prawa, przepisanie treści swojej funkcji jako return $http->get('http://www.google.com')->getBody(); sugeruje, że może to być naruszenie. Zapisywanie członów pośrednich jako zmiennych lokalnych wydaje się podejrzanym sposobem uniknięcia zasady jednej kropki.

Nie mogę podać ostatecznej odpowiedzi. Do pewnego stopnia, myślę, że to zależy od tego, jak bardzo ufasz, że $http->get() daje ci nowo utworzony obiekt, a nie wcześniej istniejącego członka.

+1

To naruszenie. – danidacar

1

Jedną z możliwości rozwiązania tego problemu jest utworzenie obiektu w obrębie m(), a następnie http-> get() wypełnienie go informacjami.

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. 
    } 
}