Wzorzec strukturalny Decorator pewnie spodoba się osobom zmęczonym tworzeniem wielu klas potomnych w procesie dziedziczenia, gdy trzeba powołać do życia obiekty podobne do siebie ale nieco inaczej skonfigurowane.
Wyobraźmy sobie tematykę hotelową, gdzie w 300 identycznych z założenia pokojach hotelowych chcemy uwzględnić po pierwsze różnice infrastrukturalne wynikające z cech konstrukcyjnych, a następnie różnice w wyposażeniu będące skutkiem bądź ustalenia konkretnego poziomu komfortu bądź zamówienia klienta.
W “standardowym” wykonaniu powołalibyśmy do życia 300 instancji klas zawierających konkretne informacje o indywidualnych cechach każdego z obiektów… lub co najwyżej zastosowalibyśmy lawinowe dziedziczenie co i tak doprowadziłoby do rozbudowanego kodu z dużą ilością if’ów i case’ów. Tutaj właśnie wchodzi do gry propozycja utworzenia kodu z wykorzystaniem wzorca Dekorator.
W rezultacie otrzymaliśmy obiekty zawierające niezbędne informacje o oczekiwanym rezultacie i przygotowane w czytelny, prosty do rozbudowy sposób.
Jak zawsze… chodzi o kod
Stwórzmy pierwszą klasę Apartment… aby umożliwić powiązanie jej z konkretnym lokalem w hotelu.
package wzorceprojektowe1;
/** @author Utracki */
public abstract class Apartment {
public abstract float cena();
public abstract String wyposażenie();
}
Teraz już mając zaczątek naszego hotelu i wspomnieliśmy już że są w nim pokoje 😉 możemy zacząć tworzyć odwzorowanie fizycznej ich postaci dla każdego istniejącego wariantu.
package wzorceprojektowe1;
/** @author Utracki */
class room2beds extends Apartment {
@Override
public float cena() { return 270f; }
@Override
public String wyposażenie() { return "Pokój dwuosobowy"; }
}
Nadszedł już czas aby zagospodarować nasz pokój wstawiając jego wyposażenie… Będziemy do tego potrzebowali dodatkowej publicznej klasy (abstrakcyjnej), która umożliwi nam wzbogacenie pokoju o niezbędne jego akcesoria.
package wzorceprojektowe1;
/** @author Utracki */
abstract class Wyposażenie extends Apartment{}
Pozostało już teraz tylko zaimplementować całe wyposażenie jakie możemy wstawić do tego pokoju. W tym celu odpowiednio multiplikujemy poniższy kod:
package wzorceprojektowe1;
/** @author Utracki */
class TV extends Wyposażenie {
private Apartment pokój;
public TV(Apartment pokój) {
this.pokój = pokój;
}
@Override
public float cena() {
return pokój.cena()+50f;
}
@Override
public String wyposażenie() {
return pokój.wyposażenie()+ " z TV";
}
}
Na koniec pozostało już tylko pokazać jak użyć powyższej struktury…
public static void main(String[] args) {
Apartment room2beds = new room2beds();
System.out.println("Pokój dwuosobowy cena: " + room2beds.cena());
System.out.println("Wyposażenie pokoju to: " + room2beds.wyposażenie());
Apartment room2beds_TV = new TV(room2beds);
System.out.println("Pokój dwuosobowy cena: " + room2beds_TV.cena());
System.out.println("Wyposażenie pokoju to: " + room2beds_TV.wyposażenie());
Zadanie: Przygotuj prostą demonstrację z wykorzystaniem wzorca, gdzie w przykładowym hostelu znajduje się 30 pokojów od 1-osobowych po 5-osobowe. Jedne wyposażone w TV, inne w jaccuzi… łóżka podwójne (małżeńskie) lub pojedyncze… itp.
Przygotuj program, który będzie pokazywał obłożenie takiego hostelu (poziom rezerwacji pokojów) z informacją jakie zasoby i w jakim stopniu są zajęte… np. wynajem kanału dla dorosłych itp. 😉
Comments are closed