Wzorzec Dekorator

DEKORATOR

Wzorzec ten należy do grupy wzorców strukturalnych.

Dekoratory dają elestyczność podobną do tej, jaką daje dziedziczenie oferując jednak w zamian znacznie rozszerzoną funkcjonalność. 

Wzorzec ten rozbudowuje strukturę bez ingerencji w istniejące obiekty. Jest pomocny w sytuacji, gdy potrzebujemy dynamicznie rozszerzyć obiekt. Co to znaczy dynamicznie? To oznacza, że nie chcemy, aby każdy obiekt danej klasy miał tę funkcjonalność, tylko aby w konkretnych warunkach obiekt był o nią poszerzony. 

To jeden z nielicznych wzorców, który zaleca dziedziczenie klasy abstrakcyjnej po klasie abstrakcyjnej. Jest bardzo podobny do Adaptera. Opakowuje komponent, czyli klasę, którą chcemy rozszerzyć. 

Dekorator możemy również wykorzystać kiedy nie chcemy lub nie możemy zmienić struktury obiektów a potrzebujemy dokonać pewnych zmian w działaniu funkcji, lub rozszerzyć obiekt.

Spróbujmy na podstawie budki z hotdogami zrozumieć istotę tego wzorca. 

Na początek stwórzmy dwie abstrakcyjne klasy: klasa Hotdog oraz klasa Dodatki:

public abstract class Hotdog {

String nazwa = "Jeszcze nie wiadomo";

public String pobierzNazwa(){ return nazwa; }
public abstract double cena();
}

 

public abstract class Dodatki extends Hotdog{
public abstract String pobierzNazwa();
}

Teraz, na podstawie klasy Hotdog stwórzmy dwa przykładowe rodzaje hotdogów: 

public class Zwykly extends Hotdog{

public Zwykly(){ nazwa = "Bulka z parowka"; }

@Override
public double cena() { return 2.50; }
}

public class Podwojny extends Hotdog{
public Podwojny(){ nazwa = "Bulka i dwie parowki"; }

@Override
public double cena() { return 3.75; }
}

W następnej kolejności,  bazując na klasie Dodatki, dodajmy kilka opcji:

public class Cebulka extends Dodatki{
Hotdog hotdog;
public Cebulka(Hotdog hotdog){
this.hotdog = hotdog;
}

public String pobierzNazwa(){
return hotdog.pobierzNazwa() + ", Chrupiaca cebulka";
}

@Override
public double cena() {
return hotdog.cena() + 0.30;
}
}
public class Ketchup extends Dodatki{
Hotdog hotdog;
public Ketchup(Hotdog hotdog){
this.hotdog = hotdog;
}

public String pobierzNazwa(){
return hotdog.pobierzNazwa() + ", Ketchup";
}

@Override
public double cena() {
return hotdog.cena() + 0.10;
}
}
public class Majonez extends Dodatki{
Hotdog hotdog;
public Majonez(Hotdog hotdog){
this.hotdog = hotdog;
}

public String pobierzNazwa(){
return hotdog.pobierzNazwa() + ", Majonez";
}

@Override
public double cena() {
return hotdog.cena() + 0.10;
}
}

Pozostało nam utworzyć tylko budkę z hotdogami i poprosić Panią z budki o coś do zjedzenia:

public class BudkaHotdog {

public static void main(String[] args){

Hotdog hotdog1 = new Zwykly();
System.out.println(hotdog1.pobierzNazwa() + " " + hotdog1.cena() + "zl");

Hotdog hotdog2 = new Podwojny();
hotdog2 = new Ketchup(hotdog2);
hotdog2 = new Majonez(hotdog2);
hotdog2 = new Cebulka(hotdog2);
System.out.println(hotdog2.pobierzNazwa() + " " + hotdog2.cena() + "zl");
}
}

Zobaczmy poniżej co otrzymaliśmy:

Bulka z parowka 2.5zl
Bulka i dwie parowki, Ketchup, Majonez, Chrupiaca cebulka 4.25zl

Należy pamiętać że zastosowanie dekoratorów może być przyczyną pojawienia się w projekcie dużej ilości małych obiektów i nadużywanie dekoratorów może doprowadzić do zdecydowanego wzrostu złożoności kodu.

Leave a Comment

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *