Vzor dekorátora v Jave
1. Prehľad
Dekoratívny vzor je možné použiť na statické alebo dynamické pripojenie ďalších zodpovedností k objektu. Dekorátor poskytuje vylepšené rozhranie k pôvodnému objektu.
Pri implementácii tohto vzoru uprednostňujeme zloženie pred dedičstvom - aby sme mohli znova a znova znižovať réžiu podtriedy pre každý zdobiaci prvok. Rekurzia spojená s týmto dizajnom môže byť použitá na ozdobenie nášho objektu toľkokrát, koľkokrát požadujeme.
2. Príklad dekoratérskeho vzoru
Predpokladajme, že máme objekt vianočného stromčeka a chceme ho ozdobiť. Výzdoba nemení samotný predmet; Je to tak, že okrem vianočného stromčeka pridávame aj nejaké ozdobné predmety, ako je girlanda, pozlátko, ozdoba na stromček, bublinkové svetlá atď.:
V tomto scenári sa budeme riadiť pôvodnými konvenciami návrhu a pomenovania Gang of Four. Najskôr vytvoríme a Vianočný stromček rozhranie a jeho implementácia:
verejné rozhranie ChristmasTree {String decorate (); }
Implementácia tohto rozhrania bude vyzerať takto:
verejná trieda ChristmasTreeImpl implementuje ChristmasTree {@Override public String decorate () {return "vianočný stromček"; }}
Teraz vytvoríme abstrakt TreeDecorator triedy pre tento strom. Tento dekoratér bude implementovať Vianočný stromček rovnaké rozhranie. Implementovaná metóda z rovnakého rozhrania bude jednoducho nazývať ozdobiť () metóda z nášho rozhrania:
verejná abstraktná trieda TreeDecorator implementuje ChristmasTree {súkromný strom ChristmasTree; // štandardné konštruktory @Override public String decorate () {return tree.decorate (); }}
Teraz vytvoríme nejaký dekoračný prvok. Tieto dekoratéry rozšíria náš abstrakt TreeDecorator triedy a upraví jej ozdobiť () metóda podľa našej požiadavky:
public class BubbleLights extends TreeDecorator {public BubbleLights (ChristmasTree tree) {super (tree); } public String decorate () {return super.decorate () + decorateWithBubbleLights (); } private String decorateWithBubbleLights () {return "with Bubble Lights"; }}
V tomto prípade platí toto:
@Test public void whenDecoratorsInjectedAtRuntime_thenConfigSuccess () {ChristmasTree tree1 = new Garland (new ChristmasTreeImpl ()); assertEquals (tree1.decorate (), "vianočný stromček s vencom"); ChristmasTree tree2 = new BubbleLights (new Garland (new Garland (new ChristmasTreeImpl ()))); assertEquals (tree2.decorate (), "vianočný stromček s vencom s vencom s bublinkovými svetlami"); }
Všimnite si, že v prvom strom1 objekt, zdobíme ho iba jedným Girlanda, zatiaľ čo druhý strom2 objekt, ktorý zdobíme jedným BubbleLights a dva Girlandy. Tento vzor nám poskytuje túto flexibilitu pri pridávaní ľubovoľného počtu dekoratérov za behu.
4. Záver
V tomto článku sme sa pozreli na návrhový vzor dekoratéra. Toto je dobrá voľba v nasledujúcich prípadoch:
- Keď chceme pridať, vylepšiť alebo dokonca odstrániť správanie alebo stav objektov
- Keď chceme iba upraviť funkčnosť jedného objektu triedy a nechať ostatné nezmenené
Celý zdrojový kód pre tento príklad je k dispozícii na GitHub.