190 likes | 345 Views
Composite. Autor: Milan Šafárik. Úvod. Tento vzor patrí do skupiny Structural Patterns . Composite je objekt, ktorý obsahuje kolekciu iných objektov. Zostavuje objekty do stromovej štruktúry, pričom umožňuje klientovi pracovať s jednoduchými i so zloženými objektmi rovnakým spôsobom.
E N D
Composite Autor: Milan Šafárik
Úvod • Tento vzor patrí do skupiny StructuralPatterns. • Composite je objekt, ktorý obsahuje kolekciu iných objektov. • Zostavuje objekty do stromovej štruktúry, pričom umožňuje klientovi pracovať s jednoduchými i so zloženými objektmi rovnakým spôsobom.
Konkrétny príklad • Majme grafický editor. K dispozícii máme jednoduché komponenty ako Text a Line. Tieto komponenty sa môžu zoskupovať do zložených komponentov, ktoré fungujú ako kontajnery. • Problémom je, že kód zaobchádza inak s primitívnymi objektmi a inak s kontajnermi, aj keď užívateľ s nimi väčšinou zaobchádza rovnako. Odlišovanie týchto komponentov robí aplikáciu komplikovanejšou.
Konkrétny príklad • Compositevzor popisuje, ako použiť rekurzívnu kompozíciu, aby klient nemusel rozlišovať tieto typy tried. • Kľúčomtohto vzoru je abstraktná trieda (Graphic), ktorá reprezentuje aj jednoduché objekty aj ich kontajnery. Deklaruje operácie, ktoré sú špecifické pre grafické objekty a aj operácie pre prístup a prácu s potomkami.
Konkrétny príklad • Podtriedy Line, Text a Rectangle implementujú draw na kreslenie čiar, textu a obdĺžnika. • Trieda Picture definuje kompozíciu grafických objektov. Picture implementujedrawzavolanímdraw jej potomkov. Vzhľadom k tomu, že picture rozhranie zodpovedá graphic rozhraniu, Picture objekty môžu skladať ďalšie picture objekty rekurzívne.
Uplatnenie • Ak chceme reprezentovať časť-celok (part-whole) hierarchiu objektov . • Ak chceme pracovať so všetkými objektmi v štruktúre jednotne a ignorovať rozdiely medzi primitívnymi objektmi a kompozíciami.
Štruktúra Typická Composite objekt štruktúra môže vyzerať napríklad takto:
Účastníci Component • Definuje rozhranie pre objekty v kompozícii. • Implementuje defaultné správanie spoločného rozhrania. • Deklaruje rozhranie pre prístup a správu jeho potomkov. • (Voliteľné) Definuje rozhranie pre prístup ku rodičovi v rekurzívnej štruktúre.
Účastníci • Leaf • Reprezentuje listové objekty. Nemá žiadnych potomkov. • Definuje správanie pre primitívne objekty. • Composite • Definuje správanie pre komponenty, ktoré majú potomkov. • Uchováva referencie na svojich potomkov . • Implementuje metódy pre prácu s potomkami definované v Componentrozhraní.
Spolupráca Klienti využívajú rozhranie triedy Component pre prácu s objektmi. Listy väčšinou vykonávajú požiadavku priamo. Ak dostane požiadavku Composite, potom ju zvyčajne prepošle potomkom, prípadne vykoná dodatočné operácie pred a po odovzdaní.
Následky • Definuje hierarchiu tried pozostávajúcu z primitívnych objektov a kompozícií. Primitívne objekty môžu byť zložené do kompozícií, a tak ďalej rekurzívne. • Klientovi uľahčuje prácu s objektmi. Klient môže zaobchádzať so zloženými a primitívnymi objektmi rovnako. Väčšinou nevie a nemal by sa starať o to, či pracuje s listom alebo zloženým objektom.
Následky • Uľahčuje pridávanie nových druhov komponentov. Novo definované Composite alebo Leaf podtriedy budú automaticky spolupracovať s existujúcimi štruktúrami a klientskym kódom. • Môže spraviť design príliš všeobecný. Je ťažšie obmedziť komponenty v kompozícii. Niekedy chceme mať kompozíciu len z vybraných komponent. Potrebné je použiť nejaké runtime kontroly.
Využitie Composite je často využívaný napríklad pri vytváraní užívateľského rozhrania. Komponenty a kontajnery na komponenty.
Ukážkový kód /** "Component" */ interface Graphic { public void print(); } /** "Leaf" */ classEllipseimplementsGraphic { publicvoidprint() { System.out.println("Ellipse"); } }
Ukážkový kód /** "Composite" */ class CompositeGraphic implements Graphic { private List<Graphic> childGraphics = new ArrayList<Graphic>(); public void print() { for (Graphic graphic : childGraphics) { graphic.print(); } } public void add(Graphic graphic) { childGraphics.add(graphic); } public void remove(Graphic graphic) { childGraphics.remove(graphic); } }
Ukážkový kód /** Client */ public class Program { public static void main(String[] args) { Ellipse ellipse1 = new Ellipse(); Ellipse ellipse2 = new Ellipse(); Ellipse ellipse3 = new Ellipse(); Ellipse ellipse4 = new Ellipse(); CompositeGraphic graphic = new CompositeGraphic(); CompositeGraphic graphic1 = new CompositeGraphic(); graphic1.add(ellipse1); graphic1.add(ellipse2); graphic1.add(ellipse3); graphic.add(graphic1); graphic.print(); } }}