Jaki jest „purystyczny” lub „poprawny” sposób uzyskiwania dostępu do właściwości obiektu z poziomu metody obiektu, która nie jest metodą pobierającą / ustawiającą?
Wiem, że spoza obiektu powinieneś użyć metody pobierającej / ustawiającej, ale od wewnątrz po prostu zrobiłbyś:
Jawa:
String property = this.property;
PHP:
$property = $this->property;
czy zrobiłbyś:
Jawa:
String property = this.getProperty();
PHP:
$property = $this->getProperty();
Wybacz mi, jeśli moja Java jest trochę zepsuta, minął rok odkąd programowałem w Javie ...
EDYTOWAĆ:
Wygląda na to, że ludzie zakładają, że mówię tylko o prywatnych lub chronionych zmiennych / właściwościach. Kiedy nauczyłem się OO, nauczono mnie, jak używać pobierających / ustawiających wartości dla każdej właściwości, nawet jeśli byłaby ona publiczna (a właściwie powiedziano mi, żebym nigdy nie upubliczniał żadnej zmiennej / właściwości). Więc od samego początku mogę zacząć od fałszywego założenia. Wygląda na to, że ludzie odpowiadający na to pytanie mogą twierdzić, że powinieneś mieć własności publiczne i że nie potrzebują one getterów i seterów, co jest sprzeczne z tym, czego mnie uczono i o czym mówiłem, chociaż może należy to omówić jako dobrze. To chyba dobry temat na inne pytanie ...
Osobiście uważam, że ważne jest, aby zachować konsekwencję. Jeśli masz metody pobierające i ustawiające, użyj ich. Jedyny przypadek, w którym miałbym bezpośredni dostęp do pola, to sytuacja, w której akcesor ma dużo narzutu. Może się wydawać, że niepotrzebnie nadymasz swój kod, ale z pewnością może to zaoszczędzić wiele bólu głowy w przyszłości. Klasyczny przykład:
Później możesz chcieć zmienić sposób działania tego pola. Może powinien być obliczany w locie, a może chciałbyś użyć innego typu dla magazynu zapasowego. Jeśli uzyskujesz dostęp do właściwości bezpośrednio, taka zmiana może zepsuć ogromną ilość kodu w jednym, zwiększonym stopniu.
źródło
Jestem dość zaskoczony, jak jednomyślny jest ten sentyment,
getters
a setery są w porządku i dobre. Proponuję artykuł zapalający Allena Holuba „ Getters And Setters Are Evil ”. To prawda, tytuł ma wartość szokującą, ale autor podaje ważne punkty.Zasadniczo, jeśli masz
getters
isetters
dla każdego pola prywatnego, sprawiasz, że te pola są równie dobre, jak publiczne. Byłoby bardzo trudno zmienić typ prywatnego pola bez efektów falowania dla każdej klasy, która to wywołujegetter
.Ponadto, z punktu widzenia ściśle OO, obiekty powinny odpowiadać na wiadomości (metody), które odpowiadają ich (miejmy nadzieję) pojedynczej odpowiedzialności. Zdecydowana większość obiektów składowych
getters
isetters
nie ma dla nich sensu;Pen.dispenseInkOnto(Surface)
ma dla mnie więcej sensu niżPen.getColor()
.Metody pobierające i ustawiające zachęcają również użytkowników klasy do żądania od obiektu pewnych danych, wykonywania obliczeń, a następnie ustawiania innej wartości w obiekcie, lepiej znanej jako programowanie proceduralne. Lepiej byłoby po prostu powiedzieć obiektowi, aby zrobił to, co zamierzałeś zrobić; znany również jako idiom Information Expert .
Jednak metody pobierające i ustawiające to zło konieczne na granicy warstw - interfejs użytkownika, wytrwałość i tak dalej. Ograniczony dostęp do elementów wewnętrznych klasy, takich jak słowo kluczowe friend w C ++, dostęp chroniony pakietem Javy, dostęp wewnętrzny .NET i wzorzec klasy znajomego może pomóc w ograniczeniu widoczności
getters
i ustawieniach tylko do tych, którzy ich potrzebują.źródło
To zależy od sposobu użytkowania nieruchomości. Załóżmy na przykład, że masz obiekt studenta, który ma właściwość name. Możesz użyć metody Get, aby pobrać nazwę z bazy danych, jeśli nie została jeszcze pobrana. W ten sposób redukujesz niepotrzebne wywołania bazy danych.
Teraz powiedzmy, że masz prywatny licznik liczb całkowitych w swoim obiekcie, który zlicza, ile razy nazwa została wywołana. Możesz chcieć nie używać metody Get z wnętrza obiektu, ponieważ spowodowałoby to niepoprawną liczbę.
źródło
PHP oferuje niezliczone sposoby radzenia sobie z tym problemem, w tym metody magiczne
__get
i__set
, ale wolę jawne metody pobierające i ustawiające. Dlatego:źródło
Być może ;)
Innym podejściem byłoby wykorzystanie prywatnej / chronionej metody do faktycznego pobierania (buforowanie / db / itp.) Oraz publicznego opakowania, które zwiększa liczbę:
PHP:
a następnie z samego obiektu:
PHP:
W ten sposób nadal możesz użyć tego pierwszego argumentu do czegoś innego (na przykład wysłanie flagi określającej, czy używać tutaj danych z pamięci podręcznej, czy nie).
źródło
Muszę pominąć ten punkt, dlaczego miałbyś używać gettera wewnątrz obiektu, aby uzyskać dostęp do właściwości tego obiektu?
Podsumowując, getter powinien wywołać metodę pobierającą, która powinna wywołać metodę pobierającą.
Więc powiedziałbym, że wewnątrz metody obiektowej dostęp do właściwości bezpośrednio, zwłaszcza patrząc, że wywołanie innej metody w tym obiekcie (która i tak po prostu uzyska bezpośredni dostęp do właściwości, a następnie ją zwróci) jest tylko bezcelowym, marnotrawnym ćwiczeniem (lub czy źle zrozumiałem pytanie ).
źródło
Purystycznym sposobem OO jest unikanie obu i przestrzeganie Prawa Demeter , stosując podejście Powiedz, nie pytaj .
Zamiast pobierać wartość właściwości obiektu, która ściśle wiąże obie klasy, użyj obiektu jako parametru np
Jeśli właściwość była rodzimym typem, np. Int, użyj metody dostępu, nazwij ją dla domeny problemowej, a nie domeny programowania.
Umożliwi to zachowanie hermetyzacji i wszelkich warunków końcowych lub niezmienników zależnych. Możesz również użyć metody ustawiającej, aby zachować dowolne warunki wstępne lub niezmienniki zależne, jednak nie wpadnij w pułapkę nazywania ich seterami, wróć do zasady Hollywood dotyczącej nazewnictwa podczas używania idiomu.
źródło
Lepiej jest używać metod akcesorów, nawet w obrębie obiektu. Oto punkty, które natychmiast przychodzą mi do głowy:
Należy to zrobić w celu zachowania spójności z dostępami dokonywanymi z zewnątrz obiektu.
W niektórych przypadkach te metody pomocnicze mogą robić coś więcej niż tylko uzyskiwanie dostępu do pola; mogą wykonywać dodatkowe przetwarzanie (jest to jednak rzadkie). W takim przypadku bezpośredni dostęp do pola oznaczałby, że brakuje tego dodatkowego przetwarzania, a program może się nie powieść, jeśli to przetwarzanie ma być zawsze wykonywane podczas tych dostępów.
źródło
Jeśli masz na myśli „najbardziej hermetyzację” przez „purystę”, to zazwyczaj deklaruję wszystkie moje pola jako prywatne, a następnie używam „this.field” z poziomu samej klasy. W przypadku innych klas, w tym podklas, uzyskuję dostęp do stanu instancji za pomocą metod pobierających.
źródło
Odkryłem, że używanie seterów / pobierających sprawia, że mój kod jest łatwiejszy do odczytania. Podoba mi się również kontrola, jaką daje, gdy inne klasy używają metod i jeśli zmienię dane, które będzie przechowywać właściwość.
źródło
Pola prywatne o właściwościach publicznych lub chronionych. Dostęp do wartości powinien przechodzić przez właściwości i być kopiowany do zmiennej lokalnej, jeśli będą używane więcej niż raz w metodzie. Jeśli i TYLKO jeśli masz resztę aplikacji tak całkowicie zmodyfikowaną, wyregulowaną i zoptymalizowaną w inny sposób, aby uzyskać dostęp do wartości przez przeglądanie ich wybranych właściwości, stało się wąskim gardłem (I to nigdy NIGDY się nie zdarzy, zapewniam), jeśli w ogóle zaczniesz rozważyć pozwolenie, by cokolwiek innego niż właściwości bezpośrednio dotykało ich zmiennych bazowych.
Programiści .NET mogą wymusić to za pomocą właściwości automatycznych, ponieważ w czasie projektowania nie można nawet zobaczyć zmiennych bazowych.
źródło
To zależy. To bardziej kwestia stylu niż cokolwiek innego i nie ma twardej zasady.
źródło
Mogę się mylić, ponieważ jestem samoukiem, ale NIGDY nie korzystam z właściwości publicznych w moich klasach Javy, są one zawsze prywatne lub chronione, więc kod zewnętrzny musi mieć dostęp przez metody pobierające / ustawiające. Jest lepszy do celów konserwacji / modyfikacji. A dla kodu klasy wewnętrznej ... Jeśli metoda getter jest trywialna, używam tej właściwości bezpośrednio, ale zawsze używam metod ustawiających, ponieważ mogę łatwo dodać kod do wyzwalania zdarzeń, jeśli chcę.
źródło
Jeśli nie
get_property()
edytuję właściwości, użyję metody publicznej, chyba że jest to specjalna okazja, taka jak obiekt MySQLi wewnątrz innego obiektu, w którym to przypadku po prostu ustawię właściwość jako publiczną i będę odnosić się do niej jako$obj->object_property
.Wewnątrz obiektu jest zawsze dla mnie właściwość $ this->.
źródło
Wygląda na to, że przy domyślnej implementacji właściwości C # 3.0 decyzja jest podejmowana za Ciebie; MUSISZ ustawić właściwość za pomocą (prawdopodobnie prywatnego) ustawiacza właściwości.
Osobiście używam prywatnego elementu członkowskiego tylko wtedy, gdy nie zrobienie tego spowodowałoby, że obiekt spadłby w mniej niż pożądany stan, na przykład podczas inicjowania lub w przypadku buforowania / leniwego ładowania.
źródło
Podoba mi się odpowiedź cmcculloh , ale wydaje się, że najbardziej poprawna jest odpowiedź Grega Hurlmana . Używaj getter / setter przez cały czas, jeśli zacząłeś ich używać od samego początku i / lub jesteś przyzwyczajony do pracy z nimi.
Na marginesie, osobiście uważam, że użycie metody getter / setter ułatwia odczytanie kodu i późniejsze debugowanie.
źródło
Jak stwierdzono w niektórych komentarzach: Czasami powinieneś, czasami nie. Wspaniałą częścią zmiennych prywatnych jest to, że możesz zobaczyć wszystkie miejsca, w których są używane, gdy coś zmienisz. Jeśli twój getter / setter robi coś, czego potrzebujesz, użyj go. Jeśli to nie ma znaczenia, decydujesz.
Można by zrobić odwrotny przypadek, że jeśli użyjesz metody pobierającej / ustawiającej i ktoś zmieni metodę pobierającą / ustawiającą, musi przeanalizować wszystkie miejsca, w których pobierający i ustawiający są używane wewnętrznie, aby sprawdzić, czy coś zepsuje.
źródło