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í a Slož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á „ "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

Ukázkový diagram třídy UML a objektů pro složený návrhový vzor. [5]

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
Definování operací souvisejících s dítětem ve složeném návrhovém vzoru. [6]

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ázet List a Složený předměty jednotně. Ale bezpečnost typu je ztraceno, protože klienti mohou provádět operace související s dětmi List 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ázet List a Složený objekty jinak. Bezpečnost typu se ale získává, protože klienti mohou ne provádět operace související s dětmi List předměty.

Zdůrazňuje kompozitní designový vzor jednotnost přes bezpečnost typu.

Diagram tříd UML

Kompozitní vzor v 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é
Kompozitní vzor v LePUS3.

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

  1. ^ 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.
  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)
  3. ^ „Kompozitní návrhový vzor - problém, řešení a použitelnost“. w3sDesign.com. Citováno 2017-08-12.
  4. ^ Scott Walters (2004). Kniha návrhů vzorů Perl. Archivovány od originál dne 08.03.2016. Citováno 2010-01-18.
  5. ^ „Kompozitní návrhový vzor - struktura a spolupráce“. w3sDesign.com. Citováno 2017-08-12.
  6. ^ „Kompozitní návrhový vzor - implementace“. w3sDesign.com. Citováno 2017-08-12.
  7. ^ Geary, David (13. září 2002). „Pohled na kompozitní designový vzor“. Java designové vzory. JavaWorld. Citováno 2020-07-20.

externí odkazy