Refaktoryzuję starszą stronę PHP OOP.
Kusi mnie, aby zacząć używać „końcowego” na zajęciach do „ make it explicit that the class is currently not extended by anything
”. Może to zaoszczędzić dużo czasu, jeśli przyjdę na zajęcia i zastanawiam się, czy mogę zmienić nazwę / usunąć / zmodyfikować protected
właściwość lub metodę. Jeśli naprawdę chcę rozszerzyć klasę, mogę po prostu usunąć ostatnie słowo kluczowe, aby odblokować je do rozszerzenia.
To znaczy, jeśli przyjdę na zajęcia, na których nie ma zajęć dla dzieci, mogę zapisać tę wiedzę, zaznaczając klasę na końcu. Następnym razem, gdy do niego dojdę, nie będę musiał ponownie przeszukiwać bazy kodu, aby sprawdzić, czy ma ona dzieci. W ten sposób oszczędzasz czas podczas refaktoryzacji.
To wszystko wydaje się rozsądnym pomysłem na oszczędzanie czasu ... ale często czytałem, że zajęcia należy kończyć tylko na rzadkie / specjalne okazje.
Może to psuje tworzenie fałszywych obiektów lub ma inne skutki uboczne, o których nie myślę.
czego mi brakuje?
źródło
Odpowiedzi:
Ktokolwiek to napisał, jest zły. Używaj
final
swobodnie, nie ma w tym nic złego. Dokumentuje, że klasa nie została zaprojektowana z myślą o dziedziczeniu, i jest to zwykle prawdą domyślnie dla wszystkich klas: projektowanie klasy, którą można w sposób znaczący odziedziczyć, wymaga więcej niż tylko usunięciafinal
specyfikatora; wymaga dużo uwagi.Dlatego używanie
final
domyślnie nie jest złe. W rzeczywistości wiele osób uważa, że powinno to być domyślne, np. Jon Skeet .Jest to rzeczywiście zastrzeżenie, ale zawsze możesz skorzystać z interfejsów, jeśli chcesz wyśmiewać swoje klasy. Jest to z pewnością lepsze niż udostępnienie wszystkich klas dziedziczeniu tylko w celu kpienia.
źródło
final
odgrywało by znacznie większą rolę.Jeśli chcesz zostawić sobie notatkę, że klasa nie ma podklas, to zrób to i użyj komentarza, po to jest. „Ostateczne” słowo kluczowe nie jest komentarzem, a używanie słów kluczowych w języku tylko w celu zasygnalizowania czegoś (i tylko Ty będziesz wiedział, co to znaczy), jest złym pomysłem.
źródło
final
prawidłowo. Nie ma w tym nic złego. A użycie funkcji języka w celu wymuszenia ograniczenia jest zawsze lepsze niż użycie komentarza.final
oznaczenia „Nigdy nie należy tworzyć podklasy tej klasy” (ze względów prawnych lub coś takiego), a nie „ta klasa obecnie nie ma dzieci, więc nadal mogę bezpiecznie zadzierać z jej chronionymi członkami”. Intencją tegofinal
jest antyteza „swobodnie edytowalnego”, afinal
klasa nie powinna mieć nawet żadnychprotected
członków!final
oznacza: „tej klasy nie można przedłużyć [na razie]”. Nic więcej, nic mniej. Czy PHP został zaprojektowany z myślą o tej filozofii nie ma znaczenia: to ma nafinal
słowo kluczowe, po wszystkim. Po drugie, argumentowanie na podstawie projektu PHP na pewno się nie powiedzie, biorąc pod uwagę, jak patchworkowy i po prostu ogólnie źle zaprojektowany PHP.Jest ładny artykuł na temat „Kiedy ogłaszać klasę jako ostateczną” . Kilka cytatów z tego:
PS Dzięki @ocramius za wspaniałą lekturę!
źródło
„końcowy” dla klasy oznacza: Chcesz podklasę? Śmiało, usuń „ostateczną” podklasę, ile chcesz, ale nie narzekaj, jeśli to nie działa. Jesteś sam.
Gdy klasę można zaklasyfikować do podklasy, jej zachowanie, na którym polegają inni, należy opisać abstrakcyjnie, zgodnie z podklasami. Dzwoniący muszą być napisani, aby oczekiwać pewnej zmienności. Dokumentacja musi być starannie napisana; nie możesz powiedzieć ludziom, żeby „patrzyli na kod źródłowy”, ponieważ kodu źródłowego jeszcze nie ma. To wszystko wysiłek. Jeśli nie oczekuję, że klasa jest podklasowana, to jest to niepotrzebny wysiłek. „końcowy” wyraźnie mówi, że wysiłek ten nie został podjęty i daje uczciwe ostrzeżenie.
źródło
Jedną z rzeczy, o których być może nie pomyślałeś, jest fakt, że DOWOLNA zmiana klasy oznacza, że musi ona przejść nowe testy jakości.
Nie oznaczaj rzeczy jako ostatecznych, chyba że naprawdę, naprawdę masz na myśli.
źródło
final
(zmianę), to muszę ją ponownie przetestować?final
. Czy to doświadczenie z pierwszej ręki?final
Klasa ma jeden podstawowy przypadek użycia. Masz klasy polimorficzne, których nie chcesz rozszerzać, ponieważ podklasa może złamać polimorfizm. Nie używaj,final
chyba że musisz zapobiec tworzeniu podklas. Poza tym jest bezużyteczny.Użycie „ostatecznego” zabiera swobodę innym, którzy chcą korzystać z twojego kodu.
Jeśli kod, który piszesz, jest tylko dla ciebie i nigdy nie zostanie udostępniony publicznie ani klientowi, możesz oczywiście zrobić z tym kodem, co chcesz. W przeciwnym razie uniemożliwisz innym korzystanie z Twojego kodu. Zbyt często musiałem pracować z interfejsem API, który byłby łatwy do rozszerzenia dla moich potrzeb, ale wtedy przeszkadzało mi „końcowe”.
Ponadto często istnieje kod, którego lepiej nie tworzyć
private
, aleprotected
. Jasne,private
oznacza „enkapsulację” i ukrywanie rzeczy uważanych za szczegóły implementacji. Ale jako programista API równie dobrze mogę udokumentować fakt, że metodaxyz
jest uważana za szczegół implementacji, a zatem może zostać zmieniona / usunięta w przyszłej wersji. Tak więc każdy, kto pomimo ostrzeżenia będzie polegał na takim kodzie, robi to na własne ryzyko. Ale może to zrobić i ponownie wykorzystać (mam nadzieję, że już przetestowany) kod i szybciej znaleźć rozwiązanie.Oczywiście, jeśli implementacja API jest open source, można po prostu usunąć „końcowy” lub uczynić metody „chronionymi”, ale następnie zmieniłeś kod i musisz śledzić zmiany w postaci łatek.
Jeśli jednak implementacja jest zamkniętym źródłem, nie możesz znaleźć obejścia lub, w najgorszym przypadku, przejść na inny interfejs API z mniejszymi ograniczeniami dotyczącymi możliwości dostosowywania / rozszerzenia.
Zauważ, że nie uważam, że „ostateczny” lub „prywatny” jest zły, ale myślę, że są po prostu zbyt często używane, ponieważ programista nie pomyślał o swoim kodzie pod względem ponownego użycia i rozszerzenia kodu.
źródło