Dekorátor
Author
Albert FloresDekorátor je jeden ze strukturálních návrhových vzorů, které řeší otázku struktury programu. Je znám také pod názvem Wrapper.
Charakteristika
Dekorátor se vytváří za účelem změny instancí tříd bez nutnosti vytvoření nových odvozených tříd, jelikož pouze dynamicky připojuje další funkčnosti k objektu. Každá dodaná funkčnost je u dekorátoru implementována jako „ozdobení“ (dekorování) jiného objektu. +more Dekorátor tedy rozšiřuje objekt, ne třídu, jak je tomu u statické dědičnosti.
Dekorátor je vhodný v následujících případech
Dynamicky přidáváme povinnosti jednotlivým objektům (bez ovlivnění jiných objektů) ** Povinnosti lze případně i odebrat * Pokud rozšiřování pomocí podtříd není praktické. Kupříkladu máme třídu pro tlačítko, kterou používáme pro 50 tlačítek a pro 10 tlačítek nyní potřebujeme nadefinovat trochu odlišnou funkčnost (např. +more okraj tlačítka). V případě použití podtříd nám vznikne 10 odvozených tříd a výsledný kód se může stát nepřehledným. * Třídní definice může být skrytá či jinak nedostupná pro tvorbu podtříd.
Implementace
UML diagram návrhového vzoru dekorátor (zmrzlina) Problematika dekorátoru bude uvedena na velmi jednoduchém příkladu, aby došlo k rychlému osvojení. +more Je zapotřebí vytvořit zmrzlinu a k ní několik odlišných polev, které zmrzlinu ozdobí. Pokud bude použit návrhový vzor dekorátor, je zapotřebí si nadefinovat základní zmrzlinu a poté si nadefinovat polevy, kterými bude zmrzlina ozdobena, viz obrázek - UML diagram. Příklad je uveden v jazyce Java, ale k pochopení základního principu postačí znalost kteréhokoliv objektově orientovaného jazyka.
Interface, který bude znázorňovat zmrzlinu
public interface Icecream { public String makeIcecream; }
Základní třída, na kterou budou dekorátory (tedy polevy) přidány, má tuto podobu
public class SimpleIcecream implements Icecream { @Override public String makeIcecream { return "Base Icecream"; } }
Následující třída tvoří jádro dekorátoru. Instance budou konstruktorem dynamicky dosazovány při tvorbě dekorátoru a po dosazení se zavolá metoda instance
abstract class IcecreamDecorator implements Icecream {
protected Icecream specialIcecream;
public IcecreamDecorator(Icecream specialIcecream) { this.specialIcecream = specialIcecream; }
public String makeIcecream { return specialIcecream.makeIcecream; } }
Nyní už je zapotřebí pouze samotných dekorátorů. Dekorátor je v tomto případě třída, která implementuje abstraktní dekorátor, viz předešlý krok. +more Jakmile je dekorátor vytvořen, je základní instance za použití konstruktoru přiřazena do nadřazené třídy. Metoda „makeIcecream“ volá základní metodu následovanou vlastní metodou „addHoney“, která rozšiřuje funkčnost o vlastní kroky.
public class HoneyDecorator extends IcecreamDecorator {
public HoneyDecorator(Icecream specialIcecream) { super(specialIcecream); }
public String makeIcecream { return specialIcecream.makeIcecream + addHoney; }
private String addHoney { return " + sweet honey"; } }
Další dekorátory jsou tvorbou shodné
public class NuttyDecorator extends IcecreamDecorator {
public NuttyDecorator(Icecream specialIcecream) { super(specialIcecream); }
public String makeIcecream { return specialIcecream.makeIcecream + addNuts; }
private String addNuts { return " + crunchy nuts"; } }
Použití dekorátoru
Nyní lze použít kterékoliv dekorátory v kterémkoliv pořadí. Tato flexibilita a proměnlivost chování instance za běhu, jak si zvolíme, je základní výhoda návrhového vzoru dekorátor
public class TestDecorator {
public static void main(String args[]) { Icecream icecream = new HoneyDecorator(new NuttyDecorator(new SimpleIcecream)); System.out.println(icecream.makeIcecream); } }
Předešlá testovací třída vytvoří takovýto výstup
"Base Icecream + crunchy nuts + sweet honey"
Shrnutí
Dekorátor je velmi podobný adaptéru, ale nepřekrývá původní protokol ošetřovaného objektu. Dekorátor je v určitých případech také vhodnější než obyčejné dědění, jelikož při vytvoření nové funkčnosti by v případě klasické dědičnosti zdědily tuto funkčnost všechny objekty a to znamená, že i ty, které by funkčnost vůbec nepotřebovaly. +more To se u dekorátoru nestane.
Literatura
PECINOVSKÝ, Rudolf. Návrhové vzory. +more 1. Vydání. Praha: CPress, 2007. 528 s. EAN 9788025115824. * GAMMA E. - HELM R. - JOHNSON R. - VLISSIDES J. Návrh programů pomocí vzorů: Stavební kameny objektově orientovaných programů. 1. Vydání. Praha: Grada, 2003 .