Java interfejsy

0

Hej, chciałem się zapytać o konkretny przykład w którym jeden interfejs (np. 8 metod) ma dwie implementacje.
Jeden z interfejsów jest zgodny ze wszystkimi tymi metodami (implementuje poprawnie 8 metod), zaś ten drugi poprawnie implementuje tylko 6 z nich, na pozostałych dwóch ma: throw new UnsupportedException();

Czy generalnie taki koncept jest okej? Czy powinno się łączyć dwie implementajce jednym interfejsem nawet jeśli nie jest w 100% zgodny?
Jeśli to nie jest ok, to co w takim wypadku? Jest na to jakiś inny koncept?

0

możesz te dwie wyodrębnić do osobnego interfejsu

2
  1. Zasada separacji interfejsów (ISP) plus zasada podstawiania (LSP) są tutaj złamane.
  2. Generalnie jest to raczej w złym guście, bo wyobraź sobie że dostajesz gdzieś obiekt opakowany tym interfejsem i co teraz? Możesz wołać te metody czy nie możesz? Skoro te 2 ostatnie metody są specyficzne dla jednej z implementacji to niech będą metodami tej implementacji a nie interfejsu. W interfejsie i tak są bezużyteczne, bo możesz ich "bezpiecznie" użyć nie wiedząc z którym obiektem masz do czynienia.
1

Wedle zasad SOLID, a dokładnie czwartej, czyli Interface segregation principle, lepiej tworzyć wiele interfejsów bardziej szczegółowych, niż jeden z wieloma klasami. Pamiętaj, że w przeciwieństwie do klas bazowych, interfejsów możesz dodawać do klasy wiele, a wtedy nie będziesz zmuszony do implementowania wszystkich metod (w tym niepotrzebnych dla danej klasy).

2

Takie rozwiązanie stosuje się jako ostateczność, gdy inaczej się nie da.

Np. niemutowalne kolekcje muszą mieć interfejs zgodny z mutowalnymi (jak List, i inne takie-takie). Ale niektórych operacji, co oczywiste, nie wspierają (np. add). W związku z czym wybuchną ci w twarz w trakcie jazdy (UnsupportedOperationException).

Łamie to kilka zasad - wspomnianą już dwukrotnie "I" w SOLID, ale także np. POLA, czyli zasadę najmniejszego zaskoczenia.

Świadczy to o tym, że wyjściowy design był, z punktu widzenia dzisiejszych potrzeb, zły. Np. nie przewidziano, że kolekcje mogą się dzielić na mutowalne i nie. I musimy w ten brzydki sposób poniewczasie "spłacić" dawny grzech pierworodny kiepskiego przewidywania.

Ale jeśli nie musimy się wykopywać z jakichś zaszlości historycznych, to w imię czego łamać dobre zasady? Z własnej inicjatywy nigdy w życiu bym czegoś takiego nie popełnił.

Jeden z moich pierwszych, nazwijmy to, mentorów, nauczył mnie takiej zasady "gwoździa w ścianie". Ze ściany wystaje gwóźdź, o który można rąbnąć deklem - powiedział, i niespiesznie łyknął zielonej herbaty z czarki. Mądry inżynier nakleił przy nim kartkę: "uwaga, gwóźdź!".

- Ile razy ktoś nie przeczyta tej kartki? - zapytał nas Mistrz, a my zacukaliśmy się niepomiernie. - Co najmniej jeden raz - wyjaśnił. Prawda ta poraziła nas. Jak temu zaradzić, zapytał? Większa kartka! Kapsułka ochronna na gwóźdź! "Zainstalować alarm dźwiękowy", radził doświadczony mechanik. "Przedefiniować pojęcie gwoździa?", próbował filozof z fakultetem.

Mistrz potrząsnął głową. "Najlepiej nie mieć gwoździa w ścianie" - rzekł. W tym momencie uczniowie doznali oświecenia.

guagg napisał(a):

Jeden z interfejsów jest zgodny ze wszystkimi tymi metodami (implementuje poprawnie 8 metod), zaś ten drugi poprawnie implementuje tylko 6 z nich [...]
Jeśli to nie jest ok, to co w takim wypadku? Jest na to jakiś inny koncept?

Jeden interfejs z 6 metodami i drugi z 2 metodami. Jeśli można sobie logicznie wyobrazić obiekt wspierający tylko te 2, czyli jeśli te funkcjonalności są od siebie niezależnie. Jeśli nie, to szerszy interfejs będzie rozszerzał węższy (sześciometodowy) o te 2 dodatkowe metody. Czyli wtedy masz interfejs 6 i drugi - rozszerzający - 2+6.

0

Dokłanie, niestety kolekcje zostały tak właśnie zaimplementowane i to był błąd designerów Java Collection API...

1 użytkowników online, w tym zalogowanych: 0, gości: 1