2010-10-21 15 views
5

Opis LOD, który widziałem (na przykład Wikipedia, C2 Wiki) mówi o braku wywoływania metod. Cytując Wikipedię:Czy Prawo Demeter stosuje się tylko do metod?

Prawo Demeter dla funkcji wymaga Metoda A M obiektu O może powołać jedynie metody z następujących rodzajów obiektów:
- O sama
- parametry M
- stworzył wszelkie obiekty/instancja ciągu M
- bezpośredni komponent o za obiekty
- zmienną globalną, dostępną przez o, w zakresie M

Ale co z dostępem do właściwości, zmiennych lub wyliczeń? Na przykład, biorąc pod uwagę to:

class FirstClass { 
    public SecondClass GetRelatedClass() { 
     return new SecondClass(); 
    } 

    public enum InnerEnum { 
     Violated, 
     NotViolated 
    } 
} 

class SecondClass { 
    public int Property {get; set;} 
    public string _variable = "Danny Demeter"; 
} 

Czy którekolwiek/wszystkie z tych naruszeń LOD? (Zignoruj ​​bezpośredni dostęp do zmiennych teraz, jeśli można ..)

void Violate(FirstClass first) { 
    SecondClass second = first.GetRelatedClass(); 
    var x = second.Property; 
    var y = second._variable; 
    var z = FirstClass.InnerEnum.Violated; 
} 

nie zrobiłbym dwa pierwsze (czy to „oficjalna” naruszeń lub nie), nie tak pewny o wyliczenia chociaż.

Odpowiedz

6

Nie mogę odpowiedzieć na pytanie enum - wydaje mi się, że standardowe zalecenie nie definiuje wyliczeń wewnątrz klasy.

W przypadku właściwości można naprawdę uznać właściwości za skróty do metod (getProperty() i setProperty(value)). W takim przypadku twoja odpowiedź brzmi, że dostęp do nieruchomości jest naruszeniem.

Ponownie, dla pól (zmiennych), powszechną praktyką nie jest ich eksponowanie, ale raczej używanie właściwości, tak naprawdę eksponowanie pól jest naruszeniem enkapsulacji.

Ostatecznie intencją Prawa Demeter jest ograniczenie wiedzy na temat implementacji między zajęciami. Dla mnie oznacza to, że wszystkie Twoje przykłady to naruszenia.

+0

Rzeczywiście. Powodem, dla którego Wiki C2 nie mówi o zmiennych instancji, polach, właściwościach, enumach, atrybutach, slotach itp. Jest po prostu dlatego, że duża część członków tej społeczności to stare Smalltalkery, w których wszystkie są i tak prywatne. Pola, atrybuty, zmienne instancji, sloty lub jakkolwiek się one nazywają, są izomorficzne do pary metod getter/setter, a ponieważ są * izomorficzne, powinno być oczywiste, że przełączanie się między polem a geterem nie powinno się zmieniać właściwości Demeter w jakikolwiek sposób.Pole powinno być po prostu traktowane jako metoda. –

1

FWIW ...

Naruszenie # 1 (x) wygląda nieobrobionego lokalizacji usługa wzorca, więc podejrzewam, że przykład nie jest to naruszenie.

Naruszenie # 2 (y) wygląda jak zapach klasy, ale generalnie nie demonstruje niczego powyżej tego, co pokazuje naruszenie 1.

Nie sądzę, że publiczne wyliczenia (z), niezależnie od zakresu, będą się liczyć tutaj z LOD.

Czy masz lepszy przykład z prawdziwego świata, aby zademonstrować swoje obawy? Bez właściwego kontekstu proste przykłady kodu mogą być w porządku lub mogą naruszać zasady projektowania.

+0

Być może, choć wydaje mi się, że wygląda to mniej, jeśli napiszesz wszystko razem (co z punktu widzenia LOD jest takie samo): 'x = first.GetRelatedClass(). Property;'. A może lokalizacja usługi jest czasami naruszeniem LOD? –

Powiązane problemy