2010-05-25 15 views
5

Poniżej przedstawiono pytanie dotyczące używania właściwości w klasie.Właściwość i enkapsulacja

Używam publicznych właściwości zamiast publicznego ujawniania zmiennych członkowskich. Większość zaleca, aby takie podejście ułatwiało hermetyzację. Jednak nie rozumiem przewagi enkapsulacji, czyniąc ją własnością.

wiele osób nie zna prawdziwego powodu używania nieruchomości. Po prostu robią to jako część standardu kodowania.

Czy ktoś może wyjaśnić, w jaki sposób właściwość jest lepsza niż publiczna zmienna członkowska i jak poprawia ona hermetyzację?

Odpowiedz

6

Enkapsulacja pomaga poprzez izolowanie klas wywołań od zmian.

Wyobraźmy sobie, że masz prostą klasę, która modeluje silnik samochodu (wszystkie przykłady OO powinny zawierać analogię do samochodu :)). Możesz mieć proste pole tak:

private bool engineRunning; 

Wystarczy podejmowania tego pola publicznych lub dostarczenie IsEngineRunning() getter nie wydaje się być inaczej.

Załóżmy teraz zrobić klasa bardziej wyrafinowane, że chcesz usunąć to pole i zastąpić go:

private bool ignitionOn; 
private bool starterWasActivated; 

Teraz, jeśli masz dużo zajęć z dostępem do starego engineRunning pola trzeba iść i zmienić je wszystkie (złe czasy).

Jeśli zamiast tego zaczął się:

public bool IsEngineRunning() 
{ 
    return this.engineRunning; 
} 

można teraz zmienić go:

public bool IsEngineRunning() 
{ 
    return ignitionOn && starterWasActivated; 
} 

i interfejs klasy pozostaje taki sam (dobre czasy).

+0

chciałbym podkreślić, że zmiana ta nie oznacza, że ​​klienci muszą być zmienione. Oznacza to tylko, że będziesz musiał ujawnić właściwość engineRunning w ten sam sposób i z tą samą semantyką jak poprzednio. Jedyna różnica polega na tym, że każda aktualizacja właściwości zapłonu i rozrusznika musiałaby również zaktualizować właściwość engineRunning. W zależności od tego, co częściej czyta się/aktualizuje, może to mieć pozytywny lub negatywny wpływ na wydajność. –

1

Niektóre myśli:

  • można zmienić wewnętrzną reprezentację danych bez wpływu na zajęcia dzwoni.

    E.g. (przed)

    public boolean isActive() { 
        return this.is_active; 
    } 
    

    (po)

    public boolean isActive() { 
        return this.is_active && this.approved && this.beforeDeadline; 
    } 
    

    Jest to szczególnie ważne, jeśli kod jest używany przez innych (czyli kod jest 3rd-Party). Do pewnego stopnia twój interfejs/API musi pozostać stabilny. Małe zmiany nie powinny wpływać na kod innego kodu, który z niego korzysta.

  • Można wykonywać bardziej złożone operacje. Rozważ zmienną is_active. Być może zmiana wartości tej zmiennej wpływa również na inne właściwości obiektu. Jeśli enkapsulujesz dostęp w metodzie, możesz zająć się tym w tej metodzie, a osoba dzwoniąca nie musi się troszczyć.

    E.g.

    public void setActive(boolean active) { 
        this.is_active = active; 
        this.startTimeout(); 
        this.updateOtherInformation(); 
    } 
    

    Wymusza więc wykonanie pewnej serii czynności. You do not polegać na tym, że wywołujący wykonuje te działania prawidłowo. Twój obiekt będzie zawsze w poprawnym stanie.

2

Spróbuję krótko. Właściwości = elastyczność

Właściwości są przydatne do tworzenia członków, których nie chcesz trzymać w klasie przez cały czas lub które są agregacjami/funkcjami istniejących członków.

Np. wiek mogą być wyprowadzane na podstawie daty urodzenia, canSwim mogą być generowane z hasLimbs & & pływa

narażając członków jak właściwości mogą być pomocne w kontaktach z nieoczekiwanymi zmianami [Czy ktoś kiedykolwiek przewidzieć wszystkich żądań klienta?] w systemach z istniejąca baza danych.

Np. Parametr isAllowed ma wartość true, gdy użytkownik ma więcej niż 18 lat i jest buforowany pod kątem wydajności. Klient chce uruchomić usługę w USA i możesz zwrócić wartość false, jeśli fałsz jest fałszowany i sprawdzać wiek tylko wtedy, gdy pamięć podręczna jest prawdziwa.

4

Lepiej eksponować właściwości zamiast zmiennych członkowskich, ponieważ to umożliwiłoby wykonanie wszystkich rodzajów sprawdzanie podczas ustawiania lub pobierania wartości zmiennej składowej.

przypuszczać u mają zmienną użytkownika:

private int id; 

i masz własność publiczną:

public int ID 
{ 
    get 
    { 
     // do something before returning 
    } 
    set 
    { 
     // do some checking here may be limits or other kind of checking 
    } 
} 
Powiązane problemy