Przejdź do głównej zawartości

Dlaczego default jest blee... Wielodziedziczenie

Piszę ten post gdyż złapałem się na tym, że nie potrafiłem uargumentować swojego przekonania dotyczącego pewnego aspektu programowania gdy padło pytanie: "dlaczego?". Dopiero później wszystko sobie przypomniałem i mam nadzieję, że ten post nie pozwoli mi już o tym zapomnieć ;).

Dawno, dawno temu, gdy ukazała się Java w wersji 8, wielu z nas zachwycało się nowym mechanizmem: metody default! Bo to takie fajne, nowe, można ograniczyć powtarzanie się kodu, no generalnie bajer. Dopiero po chwili niestety, dotarło, że wprowadzenie takiego rozwiązania to cofanie się w czasie.

 Wielodziedziczenie

Podczas lat rozwoju języków programowania pojawił się w pewnym momencie trend aby unikać stosowania rozwiązania zwanego wielodziedziczeniem. Czym jest ten mechanizm? Pozwala on na dziedziczenie z wielu klas bazowych jednocześnie. Unikanie jego stosowania, a nawet unikanie implementacji takiego mechanizmu w nowoczesnych językach jest poparte sensownymi argumentami.

Po pierwsze, może wydarzyć się problematyczna sytuacja, w której część z klas bazowych zawiera implementację tej samej metody o dokładnie tej samej definicji. Która w takim razie ma być zastosowana? Oczywiście są pewne domyślne zachowania zależne od języka oraz można zwykle określić, z której należy korzystać ale czy nie wprowadza to tylko zbędnego zamieszania?

Po drugie, zastanawiam się kiedy ostatnio potrzebowałem takiego mechanizmu? Nie przypominam sobie ani jednej sytuacji, w której byłoby mi potrzebne dziedziczenie z kilku klas. Uważam, że każdy problem jestem w stanie rozwiązać w inny sposób.

Po trzecie, stosowanie wielodziedziczenia jest sprzeczne z ideą stawiania na kompozycję ponad dziedziczenie, której jestem wielkim fanem. O tym napisano baaardzo wiele i tutaj nie dam się przekonać ;).

Ponadto jestem skłonny stwierdzić, że takie rozwiązanie nie służy pisaniu czystego, zarządzalnego kodu. Po prostu.

Wielodziedziczenie, a interfejsy

No dobra, a dlaczego w takim razie z interfejsami jest wszystko ok? Otóż dlatego, że interfejs tylko definiuje funkcjonalność, a klasa ją implementuje. Nie ma w tym wypadku miejsca na żadnego rodzaju niejasności.

Wracając do tematu

Miałem pisać przecież o metodach default, a cały tekst jest o wielodziedziczeniu. Okazuje się bowiem, że developerzy Oracle'a wprowadzili nam cichaczem do języka mechanizm wielodziedziczenia pod nazwą metod default. Bo jak inaczej nazwać to, że interfejs zyskuje możliwość implementacji metody?
Wprowadzenie mechanizmu metod default jest uargumentowane potrzebą rozbudowy API Javy (chociażby biblioteki streamów) i jestem to w stanie zaakceptować ale jestem zdania, że trzeba z niego korzystać ostrożnie i wyłącznie w przypadkach niezbędnych (jak np. chęć rozbudowy biblioteki bez wpływu na działanie korzystającego z niej kodu).

Komentarze

Popularne posty z tego bloga

Aplikacja czasu rzeczywistego w Spring i AngularJS

Naszła mnie potrzeba aby utworzyć pewien dashboard, który reagowałby na zmiany przychodzące z serwera. Jako, że tworzę swoje aplikacje z wykorzystaniem Spring Boot (backend) i AngularJS (frontend) to o komunikacje serwer -> klient należy zadbać samemu. Po pospiesznej analizie tematu okazało się, że taką komunikację zapewnia protokół WebSockets (co dla niektórych może jest oczywiste, lecz dla mnie nie było). Co trzeba zrobić? Zestawić połączenie pomiędzy serwerem, a klientem i przesyłać wiadomości. Proste? Proste. No to jazda.
Projekt Kombinacja Spring Boot i AngularJS (angular w wersji 1) tak mi się spodobała, że utworzyłem sobie własny archetyp mavena, aby szybko móc tworzyć kolejne proste aplikacje. Jest on dostępny na moim GitHubie. Instrukcje tworzenia z niego projektu są w Readme, nie będę się powtarzał.
Eventy Taka aktualizacja danych musi być wywoływana przez jakieś zdarzenie. Na potrzeby przykładu wykorzystałem springowe eventy. Eventem w springu może być zwykłe POJO. W moi…

Immutable collections - Java

Mierzenie się z kolekcjami i poprawnym ich wykorzystaniem jest problematyczne dla początkujących programistów. Jak często widzieliście w jakimś kodzie fragment typu:
cart.getProducts().add(product); Sam pisałem niegdyś takie brzydkie rzeczy. W czasie, w którym wyrabiałem sobie moje skromne doświadczenie wypracowałem sobie jednak pewne zasady jak postępować z kolekcjami. Ktoś mógłby się ze mną spierać - nawet podając sensowne argumenty ale w mojej pracy trzymanie się tych nawyków sprawdza się i na razie się ich trzymam.
 W czym problem? Przedstawiony wyżej fragment kodu to wyraźne złamanie zasady enkapsulacji. Skoro obiekt udostępnia swoje wnętrze (w typ przypadku jakąś kolekcję) i można z tym robić wszystko co się nam spodoba to po co te wszystkie modyfikatory dostępu i po co w ogóle taki obiekt? Skoro obiekt, który posiada jako swoją właściwość (property) jakąś listę i udostępnia ją tak po prostu na zewnątrz to może okazać się, że biedny obiekcik jest nieświadomy, że ktoś mu grzebie w…