Složený vzor - Composite pattern
v softwarové inženýrství, složený vzor je rozdělení návrhový vzor. Složený vzor popisuje skupinu objektů, se kterými se zachází stejně jako s jednou instancí stejného typu objektu. Záměrem kompozitu je „skládat“ objekty do stromových struktur, aby představovaly hierarchie celého celku. Implementace kompozitního vzoru umožňuje klientům zacházet s jednotlivými objekty a kompozicemi jednotně.[1]
Přehled
Kompozitní[2]designový vzor je jedním z dvaceti tří známých GoF návrhové vzory které popisují, jak řešit opakující se konstrukční problémy při navrhování flexibilního a opakovaně použitelného objektově orientovaného softwaru, tj. objektů, které se snadněji implementují, mění, testují a znovu používají.
Jaké problémy může kompozitní návrhový vzor vyřešit?[3]
- Hierarchie částečného celku by měla být zastoupena, aby klienti mohli zacházet s částmi a celými objekty jednotně.
- Hierarchie celého celku by měla být reprezentována jako stromová struktura.
Při definování (1) Část
objekty a (2) Celý
objekty, které fungují jako kontejnery Část
objekty, klienti s nimi musí zacházet samostatně, což komplikuje kód klienta.
Jaké řešení popisuje kompozitní návrhový vzor?
- Definujte jednotný
Součástka
rozhraní pro obě části (List
) objekty a celé (Složený
) objekty. - Individuální
List
objekty implementujíSoučástka
přímé rozhraní aSložený
namítá předávání požadavků jejich podřízeným komponentám.
To umožňuje klientům pracovat prostřednictvím Součástka
rozhraní k léčbě List
a Složený
předměty jednotně:List
objekty provádějí požadavek přímo a Složený
objekty předávají požadavek svým podřízeným komponentám rekurzivně dolů stromovou strukturu. Tím se třídy klientů snáze implementují, mění, testují a znovu používají.
Viz také diagram tříd a objektů UML níže.
Motivace
Při práci s daty ve stromové struktuře musí programátoři často rozlišovat mezi listovým uzlem a větví. Díky tomu je kód složitější, a proto náchylnější k chybám. Řešením je rozhraní, které umožňuje jednotné zpracování složitých a primitivních objektů. v objektově orientované programování, kompozit je objekt navržený jako kompozice jednoho nebo více podobných objektů, všechny vykazující podobnou funkčnost. Toto se nazývá „má "vztah mezi objekty.[4] Klíčovým konceptem je, že můžete manipulovat s jednou instancí objektu stejně, jako byste manipulovali s jejich skupinou. Operace, které můžete provádět se všemi složenými objekty, mají často a nejmenší společný jmenovatel vztah. Například pokud definujete systém pro zobrazování seskupených tvarů na obrazovce, bylo by užitečné definovat změnu velikosti skupiny tvarů, aby měla stejný účinek (v určitém smyslu) jako změna velikosti jednoho tvaru.
Kdy použít
Složený by měl být použit, když klienti ignorují rozdíl mezi kompozicemi objektů a jednotlivými objekty.[1] Pokud programátoři zjistí, že používají více objektů stejným způsobem a často mají téměř identický kód pro zpracování každého z nich, pak je kompozitní dobrá volba; v této situaci je méně složité považovat primitiva a kompozity za homogenní.
Struktura
Třída a objektový diagram UML
Ve výše uvedeném UML třídní diagram, Klient
třída neodkazuje na List
a Složený
třídy přímo (samostatně). Místo toho Klient
odkazuje na běžné Součástka
rozhraní a může zacházet List
a Složený
jednotně.
The List
třída nemá žádné děti a implementuje Součástka
rozhraní přímo.
The Složený
třída udržuje kontejner dítěteSoučástka
předměty (děti
) a předá jim tyto žádosti děti
(pro každé dítě u dětí: child.operation ()
).
Diagram spolupráce objektů ukazuje interakce za běhu: V tomto příkladu Klient
objekt odešle požadavek na nejvyšší úroveň Složený
objekt (typu Součástka
) ve stromové struktuře. Požadavek je předán (proveden) všem dětem Součástka
předměty (List
a Složený
objekty) dolů stromovou strukturu.
- Definování operací souvisejících s dětmi
Existují dvě varianty návrhu pro definování a implementaci operací souvisejících s dětmi, jako je přidání / odebrání podřízené komponenty do / z kontejneru (přidat (podřízený) / odebrat (podřízený)
) a přístup k podřízené komponentě (getChild ()
):
- Návrh pro jednotnost: Operace související s dětmi jsou definovány v
Součástka
rozhraní. To umožňuje klientům zacházetList
aSložený
předměty jednotně. Ale bezpečnost typu je ztraceno, protože klienti mohou provádět operace související s dětmiList
předměty. - Provedení pro bezpečnost typu: Operace související s dětmi jsou definovány pouze v
Složený
třída. Klienti musí zacházetList
aSložený
objekty jinak. Bezpečnost typu se ale získává, protože klienti mohou ne provádět operace související s dětmiList
předměty.
Zdůrazňuje kompozitní designový vzor jednotnost přes bezpečnost typu.
Diagram tříd UML
- Součástka
- je abstrakce pro všechny komponenty, včetně složených
- deklaruje rozhraní pro objekty ve složení
- (nepovinné) definuje rozhraní pro přístup k rodiči komponenty v rekurzivní struktuře a implementuje jej, pokud je to vhodné
- List
- představuje listové objekty v kompozici
- implementuje všechny metody komponent
- Složený
- představuje složenou komponentu (komponenta s dětmi)
- implementuje metody manipulace s dětmi
- implementuje všechny komponenty metody, obvykle jejich delegováním na své podřízené
Variace
Jak je popsáno v Designové vzory, vzor také zahrnuje zahrnutí metod podřízené manipulace do hlavního rozhraní komponenty, nejen do podtřídy Composite. Novější popisy někdy tyto metody vynechávají.[7]
Příklad
Následující příklad napsaný v Jáva, implementuje grafickou třídu, kterou může být elipsa nebo kompozice několika grafik. Každá grafika může být vytištěna. v Backus-Naurova forma,
Grafika :: = elipsa | GraphicList GraphicList :: = prázdný | Graphic GraphicList
Mohlo by to být rozšířeno o implementaci několika dalších tvarů (obdélník atd.) A metod (přeložit, atd.).
Jáva
import java.util.ArrayList;/** "Součástka" */rozhraní Grafický { // Vytiskne grafiku. veřejnost prázdnota tisk();}/ ** „Kompozitní“ * /třída CompositeGraphic nářadí Grafický { // Sbírka podřízené grafiky. soukromé finále ArrayList<Grafický> childGraphics = Nový ArrayList<>(); // Přidá grafiku do kompozice. veřejnost prázdnota přidat(Grafický grafický) { childGraphics.přidat(grafický); } // Vytiskne grafiku. @ Přepis veřejnost prázdnota tisk() { pro (Grafický grafický : childGraphics) { grafický.tisk(); //Delegace } }}/ ** „List“ * /třída Elipsa nářadí Grafický { // Vytiskne grafiku. @ Přepis veřejnost prázdnota tisk() { Systém.ven.tisk("Elipsa"); }}/ ** Klient * /třída CompositeDemo { veřejnost statický prázdnota hlavní(Tětiva[] args) { // Inicializujte čtyři elipsy Elipsa elipsa1 = Nový Elipsa(); Elipsa elipsa2 = Nový Elipsa(); Elipsa elipsa3 = Nový Elipsa(); Elipsa elipsa4 = Nový Elipsa(); // Vytvoří dva kompozity obsahující elipsy CompositeGraphic grafický2 = Nový CompositeGraphic(); grafický2.přidat(elipsa1); grafický2.přidat(elipsa2); grafický2.přidat(elipsa3); CompositeGraphic grafický3 = Nový CompositeGraphic(); grafický3.přidat(elipsa4); // Vytvořte další grafiku, která obsahuje dvě grafiky CompositeGraphic grafický1 = Nový CompositeGraphic(); grafický1.přidat(grafický2); grafický1.přidat(grafický3); // Vytiskne celou grafiku (čtyřikrát řetězec „Elipsa“). grafický1.tisk(); }}
Viz také
Reference
- ^ A b Gamma, Erich; Richard Helm; Ralph Johnson; John M. Vlissides (1995). Návrhové vzory: Prvky opakovaně použitelného objektově orientovaného softwaru. Addison-Wesley. str.395. ISBN 0-201-63361-2.
- ^ Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (1994). Návrhové vzory: Prvky opakovaně použitelného objektově orientovaného softwaru. Addison Wesley. str.163ff. ISBN 0-201-63361-2.CS1 maint: více jmen: seznam autorů (odkaz)
- ^ „Kompozitní návrhový vzor - problém, řešení a použitelnost“. w3sDesign.com. Citováno 2017-08-12.
- ^ Scott Walters (2004). Kniha návrhů vzorů Perl. Archivovány od originál dne 08.03.2016. Citováno 2010-01-18.
- ^ „Kompozitní návrhový vzor - struktura a spolupráce“. w3sDesign.com. Citováno 2017-08-12.
- ^ „Kompozitní návrhový vzor - implementace“. w3sDesign.com. Citováno 2017-08-12.
- ^ Geary, David (13. září 2002). „Pohled na kompozitní designový vzor“. Java designové vzory. JavaWorld. Citováno 2020-07-20.
externí odkazy
- Složený vzor implementace v Javě
- Popis složeného vzoru z úložiště portlandských vzorů
- Složený vzor v UML a v LePUS3, formálním modelovacím jazyce
- Třída :: Delegace na CPAN
- „The End of Inheritance: Automatic Run-time Interface Building for Aggregated Objects“ podle Paul Baranowski
- PerfectJPattern Open Source Project, Poskytuje komponentní implementaci kompozitního vzoru v Javě
- [1] Trvalá implementace založená na prostředí Java
- Kompozitní návrhový vzor