Wpis z mikrobloga

Powiedzmy, że mam narzuconą strukturę klas i nie mogę tam nic zmieniać:
- Narzedzia
- NarzedzieBudowlane extends Narzedzia
- NarzedzieBiurowe extends Narzedzia
- NarzedziaBazaDanych

Klasa NarzedziaBazaDanych w jednej z metod zwraca List, na której znajdują się zarówno obiekty NarzedzieBudowlane, jak i NarzedzieBiurowe.

Ja mam stworzyc metodę przyjmującą jako parametr tę właśne listę i z tej całej listy wyciągnąć tylko obiekty NarzedziaBudowlane i stworzyć z nich osobną listę.

private static List createListOfNarzedziaBudowlane(List narzedzia) {
List narzedziaBudowlane = new ArrayList<>();

for (Narzedzie n : narzedziaBudowlane) {
if (n instanceof NarzedzieBudowlane) {
narzedziaBudowlane.add((NarzedziaBudowlane) n);
}
}

return narzedziaBudowlane;
}

1. Czy rozwiązanie takie jak powyżej jest dobre? Czy poniższe rzutowanie da się w jakiś sposób ominąć lub zastąpić?
narzedziaBudowlane.add((NarzedziaBudowlane) n);
Ponieważ samo narzedziaBudowlane.add(n); nie przejdzie.
A może lepiej jest to zrobić w inny sposób?

2. Czy białe wolne linie po List narzedziaBudowlane = new ArrayList<>(); oraz przed return narzedziaBudowlane; są spoko czy raczej się ich nie stosuje?

#java #programowanie
  • 6
@ArcadiusK:

A może lepiej jest to zrobić w inny sposób?

Jeżeli używasz polimorfizmu tylko po to, żeby później przy pomocy instanceofa filtrować obiekty, to znaczy, że raczej nie jest on tam potrzebny. Generalnie spoko jeżeli się uczysz i chcesz sobie na tym coś potestować, ale prawdopodobnie nie powinieneś łączyć ze sobą tych dwóch typów, skoro później chcesz je od siebie rozdzielać.

Białe wiersze zazwyczaj oznaczają, że Twoja metoda jest zbyt skomplikowana
@Eoghan: Ta struktura została mi narzucona i nic z tym nie jestem w stanie zrobić ;) m.in. stąd moje pytanie, bo właśnie ostatnio czytając o polimorfiźmie zwracali uwagę na to co piszesz i był tam też przykład podobnego rzutowania jako nienajlepszej praktyki i efektu popełnienia błędu właśnie na poziomie projektowania struktury klas. Ale wolałem się upewnić czy nie ma może lepszego sposoby w tym przypadku niż to co naskrobałem.
1. Czy rozwiązanie takie jak powyżej jest dobre? Czy poniższe rzutowanie da się w jakiś sposób ominąć lub zastąpić?

narzedziaBudowlane.add((NarzedziaBudowlane) n);

Ponieważ samo narzedziaBudowlane.add(n); nie przejdzie.

A może lepiej jest to zrobić w inny sposób?


@ArcadiusK: to nie jest programowanie obiektowe, interfejsy wykorzystuje się po to, żeby ekstrahować wspólne zachowania, czyli metody. Tutaj nie ma metod, sam podział polega na tym, że coś jest czymś, a nie co dane coś potrafi
private static List createListOfNarzedziaBudowlane(List narzedzia) {

List narzedziaBudowlane = new ArrayList<>();


for (Narzedzie n : narzedziaBudowlane) {

if (n instanceof NarzedzieBudowlane) {

narzedziaBudowlane.add((NarzedziaBudowlane) n);

}

}


return narzedziaBudowlane;

}


@ArcadiusK:

private static List createListOfNarzedziaBudowlane(List narzedzia) {
return narzedzia.stream()
.filter(tool -> tool instanceof NarzedzieBudowlane)
.map(t -> ((NarzedzieBudowlane) t))
.collect(toList());
}