Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Composite [kompozit, ne kompozajt]. Composite Výslovnost  kompozit, ne kompozajt Účel  Popisuje, jak postavit hierarchii tříd složenou ze dvou druhů.

Podobné prezentace


Prezentace na téma: "Composite [kompozit, ne kompozajt]. Composite Výslovnost  kompozit, ne kompozajt Účel  Popisuje, jak postavit hierarchii tříd složenou ze dvou druhů."— Transkript prezentace:

1 Composite [kompozit, ne kompozajt]

2 Composite Výslovnost  kompozit, ne kompozajt Účel  Popisuje, jak postavit hierarchii tříd složenou ze dvou druhů objektů Atomických (primitivních) Složených (rekurzivně složených z primitivních a dalších složených objektů)  Jednotný přístup k atomickým i složeným objektům (kontejnery) Motivace  Grafický editor Vytváření složitých schémat z primitivních komponent Použití těchto schémat na vytvoření ještě složitějších schémat  Hloupá implementace – bez Composite Definuje třídy pro grafická primitiva (Line, Text, Rect) a třídy jako jejich kontejnery Kód používající tyto třídy musí rozlišovat primitiva a kontejnery  Lepší implementace - Composite pattern Klient nemusí rozlišovat

3 Příklad: Model tříd Struktura:  Abstraktní třída Graphic (Component) Reprezentuje primitivní třídy i kontejner Deklaruje metodu Draw() Deklaruje metody pro správu potomků (případně poskytuje defaultní definice)  Primitivní podtřídy (Leaf) přímo vykonávají své metody Draw()  Kontejnery (Composite) definují Draw() a metody pro správu potomků Delegují Draw() na všechny své potomky Component Composite Leaves

4 Použití GUI  Komponenty-kontejnery na komponenty Obecné (Panel, Container) Speciální (menu, strom)  AWT, Swing Reprezentace XML Reprezentace aritmetického výrazu  Nebo programu (složený příkaz) Struktura souborů a adresářů java.awt

5 Composite – obecná struktura

6 Composite – účastníci Component (Graphic)  Deklaruje interface pro objekty v kompozici  Implementuje defaultní chování společného interface  Deklaruje interface pro správu a přístup k potomkům  Uchovává referenci na předka (volitelně) Leaf (Rectangle, Line, Text, atd.)  Reprezentuje listové objekty v kompozici, nemá potomky  Definuje chování primitivních objektů Composite (Picture)  Definuje chování komponent, které potomky mají  Uchovává potomky ve vhodné datové struktuře a umožňuje jejich správu Client  Používá objekty v kompozici přes interface Component

7 Důsledky Definuje hierarchii tříd skládajících se z primitivních a složených objektů, rekurzivně  Kdykoliv klientský kód předpokládá primitivní objekt, může také použít složený objekt Zjednodušuje klienta  Může zacházet stejně se složenými i primitivními objekty  Nemusí je rozlišovat – jednodušší kód Umožňuje jednoduché přidávání nových komponent  Nově definované Composite nebo Leaf třídy automaticky fungují s existujícími strukturami i klientským kódem  Na klientovi se nemusí nic měnit Může Váš design učinit až příliš obecným  Jednoduché přidání nových komponent naopak omezuje možnosti, jak omezit typy komponent ve složeném objektu  Je potřeba použít run-time kontroly

8 Implementace – „a co děti?“ Deklarace operací s potomky ( add, remove, getChild )  Operace pro správu dětí nemají smysl pro listy – kam s nimi? V root Component – přináší transparentnost, méně bezpečné  Preferovaná varianta podle GoF  „Divné“ operace v listech, řešit výjimkami V Composite – přináší bezpečnost, odnáší transparentnost  Chyby (snaha přidat potomek k listu) zachyceny už při kompilaci  Leaf a composite mají jiný interface Ve třídě Component definovat virtuální metodu GetComposite() vracející defaultně null Datová struktura pro uchování potomků  Pole, spojové seznamy, stromy, hashovací tabulky, …  Nedefinovat kolekci ve třídě Component ! Pořadí potomků  Composite může definovat pořadí potomků, které se může v aplikaci využít Příklad v Graphics: front-to-back order  Použít vhodnou datovou strukturu  Přizpůsobit interface metod pro přístup a správu potomků, lze použít Iterator pattern

9 Implementace Explicitní reference na rodiče  Jednodušší pohyb po stromové struktuře, použití ve vzoru Chain of Responsibility  Referenci definovat v Component Leaf a Composite ji dědí spolu s funkcemi s ní případně spojenými  Zajistit, aby reference byla aktuální Měnit ji pouze když je dítě přidáváno nebo odstraňováno z Composite (Add, Remove) Mazání komponent  Mazaný Composite by měl být zodpovědný za smazání svých dětí Výjimka: sdílené komponenty  Při mazání dítěte je potřeba jej odebrat z rodičovy kolekce Composite.Operation()  Nemusí se delegovat pouze na potomky Př.: Composite.Price() vrací cenu objektu: rekurzivně zavolá na všechny své děti a jejich návratové hodnoty sečte

10 Implementace - vylepšení Cachování pro zlepšení výkonnosti  Při častém procházení nebo prohledávání velkých kompozic je dobré evidovat informace z posledního průchodu / hledání  Composite cachuje informace o dětech Př.: Picture cachuje ohraničenou viditelnou oblast svých dětí, během překreslování je nemusí procházet znovu  Je třeba invalidovat cache při změně Jsou potřeba reference na předky a interface k invalidaci cache Sdílení komponent  Sdílet komponenty např. kvůli úspoře paměti  Složitější, když komponenta může mít nejvýše jednoho rodiče  Řešení – děti mají více rodičů - DAG Problémy s víceznačností, když je požadavek propagován směrem nahoru ve struktuře

11 Příklad class Equipment { protected: string name; public: Equipment(string name):name(name) {} virtual ~Equipment() {} virtual void add(Equipment* equipment) =0; virtual void remove(Equipment* equipment) =0; virtual int getTotalPrice() =0; string getName() {return this->name;} }; Component (abstract child methods) class Keyboard : public Equipment { private: int price; public: Keyboard(string name, int price) : Equipment(name), price(price) {} int getTotalPrice() {return this->price;} void add(Equipment*) { throw RtExc(); } void remove(Equipment*) { throw RtExc(); } }; Leaf (not implemented child methods)

12 Příklad class PC : public Equipment { private: List children; public: PC(String name) : Equipment(name) {}; ~PC() { for (Equipment* equipment : children) delete equipment; } int getTotalPrice() { int total = 0; for (Equipment* equipment : children) total += equipment->getTotalPrice(); return total; } void add(Equipment* equipment) { children.add(equipment); } void remove(Equipment* equipment) {children.remove(equipment);} }; Composite Implementované child methods Využití potomků pro výpočet celkové částky

13 Související vzory Command  Složený MacroCommand Decorator  Často používán s Composite  Interface třídy Component z Decoratoru navíc obsahuje metody pro práci s dětmi Flyweight  Sdílení komponent Iterator  Procházení potomků různými způsoby Visitor  Lokalizuje operace a chování, které by jinak byly rozprostřeny v Composite i Leaf třídách

14 Shrnutí Zakrytí rozdílu mezi objektem a kolekcí těchto objektů  Zjednodušení práce klienta Možnost cacheování výsledků získaných z potomků  Urychlení běhu programu Struktura

15 Composite Zdroje  Příklady použití in-rdfowl.html  Vše ostatní GoF C# návrhové vzory, Judith Bishopová


Stáhnout ppt "Composite [kompozit, ne kompozajt]. Composite Výslovnost  kompozit, ne kompozajt Účel  Popisuje, jak postavit hierarchii tříd složenou ze dvou druhů."

Podobné prezentace


Reklamy Google