Linker (designový vzor)

Aktuální verze stránky ještě nebyla zkontrolována zkušenými přispěvateli a může se výrazně lišit od verze recenzované 9. května 2016; kontroly vyžadují 16 úprav .
linker
Kompozitní
Typ strukturální
Popsáno v Návrhové vzory Ano

Složený vzor je strukturní  návrhový vzor , ​​který kombinuje objekty do stromové struktury , která představuje hierarchii od konkrétního k celku. Linker umožňuje klientům přistupovat k jednotlivým objektům a skupinám objektů stejným způsobem.

Účel

Vzor definuje hierarchii tříd, které mohou současně sestávat z primitivních a komplexních objektů, zjednodušuje architekturu klienta a usnadňuje proces přidávání nových typů objektů.

Popis

Šablona diagramu UML :

Příklady implementace

Příklad Java

Zdroj Java import java.util.List ; import java.util.ArrayList ; /** "Component" */ interface Graphic { //Vytiskne grafiku. veřejný neplatný tisk (); } /** "Composite" */ class CompositeGraphic implements Graphic { //Sbírka podřízené grafiky. private List < Graphic > mChildGraphics = new ArrayList < Graphic > (); //Vytiskne grafiku. public void print () { for ( Graphic graphic : mChildGraphics ) { graphic . tisknout (); } } //Přidá grafiku do kompozice. public void add ( Graphic graphic ) { mChildGraphics . přidat ( grafika ); } //Odstraní grafiku z kompozice. public void remove ( Graphic graphic ) { mChildGraphics . odstranit ( grafika ); } } /** "Leaf" */ class Ellipse implements Graphic { //Vytiskne grafiku. public void print () { System . ven . println ( "Elipsa" ); } } /** Klient */ public class Program { public static void main ( String [] args ) { //Inicializace čtyř elips Ellipse ellipse1 = new Elipsa (); Elipsa elipsa2 = nová Elipsa (); Elipsa elipsa3 = nová Elipsa (); Elipsa elipsa4 = nová Elipsa (); //Inicializace tří složených grafik CompositeGraphic graphic = new CompositeGraphic (); CompositeGraphic graphic1 = new CompositeGraphic (); CompositeGraphic graphic2 = new CompositeGraphic (); //Složí grafiku graphic1 . přidat ( elipsa1 ); grafika1 . přidat ( elipsa2 ); grafika1 . přidat ( elipsa3 ); grafický 2 . přidat ( elipsa4 ); grafický . přidat ( grafika1 ); grafický . přidat ( grafika2 ); //Vytiskne kompletní grafiku (čtyřnásobek řetězce "Ellipse"). grafický . tisknout (); } }

Příklad v C#

Zdrojový text v C# class MainApp { static void Main () { // Vytvoření stromové struktury Složený kořen = new Composite ( "root" ); kořen . Přidat ( nový list ( "List A" )); kořen . Přidat ( nový list ( "list B" )); Composite comp = new Composite ( "CompositeX" ); komp . Přidat ( nový list ( "List XA" )); komp . Přidat ( nový list ( "LeafXB" )); kořen . Přidat ( comp ); kořen . Přidat ( nový list ( "list C" )); // Přidání a odebrání listu Leaf leaf = new Leaf ( "Leaf D" ); kořen . Přidat ( list ); kořen . Odebrat ( list ); // Rekurzivně zobrazí kořen stromu . displej ( 1 ); // Počkejte na uživatelskou konzoli . číst (); } } /// <summary> /// Komponenta - komponenta /// </summary> /// <li> /// <lu>deklaruje rozhraní pro skládací objekty;</lu> /// <lu>poskytuje vhodné implementační výchozí operace, /// společné pro všechny třídy;</lu> /// <lu>deklaruje rozhraní pro přístup a manipulaci s dětmi;</lu> /// <lu>definuje rozhraní pro přístup k rodičovi komponenty v rekurzivní struktuře /// a volitelně ji implementuje. Tato funkce je volitelná;</lu> /// </li> abstract class Component { protected string name ; // Konstruktor public Komponenta ( string name ) { this . jmeno = jmeno ; } public abstract void Display ( int depth ); } /// <summary> /// Složený – složený objekt /// </summary> /// <li> /// <lu>definuje chování komponent, které mají potomky;</lu> /// < lu >ukládá podřízené komponenty;</lu> /// <lu>implementuje operace související s podřízenou správou a rozhraním /// třídy <viz cref="Component"/></lu> /// </li> Composite : Component { private List < Component > children = new List < Component >(); // Konstruktor public Composite ( string name ) : base ( name ) { } public void Přidat ( komponenta komponenty ) { děti . Přidat ( komponenta ); } public void Odebrat ( komponenta komponenty ) { děti . Odebrat ( komponent ); } public override void Display ( int depth ) { Console . WriteLine ( nový řetězec ( '-' , hloubka ) + jméno ); // Rekurzivně zobrazí podřízené uzly foreach ( komponenta komponenta v potomcích ) { komponenta . Displej ( hloubka + 2 ); } } } /// <summary> /// List - list /// </summary> /// <remarks> /// <li> /// <lu>představuje listový uzel kompozice a nemá žádné potomky;< /lu> /// <lu>definuje chování primitivních objektů v kompozici;</lu> /// </li> /// </remarks> class Leaf : Component { // Konstruktor public Leaf ( string name ) : základ ( jméno ) { } public override void Display ( int depth ) { Console . WriteLine ( nový řetězec ( '-' , hloubka ) + jméno ); } }

Příklad C++

Zdrojový text v C++ #include <iostream> #include <seznam> #include <algoritmus> #include <paměť> třída IText { veřejnost : typedef std :: shared_ptr < IText > SPtr ; virtuální void draw () = 0 ; virtual void add ( const SPtr & ) { throw std :: runtime_error ( "IText: Nelze přidat do listu" ); } virtual void remove ( const SPtr & ){ throw std :: runtime_error ( "IText: Nelze odstranit z listu" ); } }; class CompositeText : public IText { veřejnost : void add ( const SPtr & sptr ){ děti_ . push_back ( sptr ); } void remove ( const SPtr & sptr ){ děti_ . odstranit ( sptr ); } void nahradit ( const SPtr & oldValue , const SPtr & newValue ){ std :: nahradit ( children_ . begin (), children_ . end (), oldValue , newValue ); } virtuální void kreslení (){ pro ( SPtr & sptr : children_ ){ sptr -> draw (); } } soukromý : std :: seznam < SPtr > children_ ; }; class Letter : public IText { veřejnost : Písmeno ( char c ) : c_ ( c ) {} virtuální void kreslení (){ std :: cout << c_ ; } soukromý : char c_ ; }; int main (){ SloženýText věta ; IText :: SPtr lSpace ( nové písmeno ( ' ' )); IText :: SPtr lExcl ( nové písmeno ( '!' )); IText :: SPtr lComma ( nové písmeno ( ',' )); IText :: SPtr lNewLine ( nové písmeno ( '\n' )); IText :: SPtr lH ( nové písmeno ( 'H' )); // písmeno 'H' IText :: SPtr le ( nové písmeno ( 'e' )); // písmeno 'e' IText :: SPtr ll ( nové písmeno ( 'l' )); // písmeno 'l' IText :: SPtr lo ( nové písmeno ( 'o' )); // písmeno 'o' IText :: SPtr lW ( nové písmeno ( 'W' )); // písmeno 'W' IText :: SPtr lr ( nové písmeno ( 'r' )); // písmeno 'r' IText :: SPtr ld ( nové písmeno ( 'd' )); // písmeno 'd' IText :: SPtr li ( nové písmeno ( 'i' )); // písmeno 'i' IText :: SPtr wHello ( new CompositeText ); wHello -> add ( lH ); wHello -> add ( le ); wHello -> add ( ll ); wHello -> add ( ll ); wHello -> add ( lo ); IText :: SPtr wWorld ( new CompositeText ); // slovo "World" wWorld -> add ( lW ); wWorld -> add ( lo ); wWorld -> add ( lr ); wWorld -> add ( ll ); wWorld -> add ( ld ); věta . přidat ( wAhoj ); věta . přidat ( lčárka ); věta . přidat ( lSpace ); věta . přidat ( svět ); věta . přidat ( lExcl ); věta . přidat ( lNový řádek ); věta . kreslit (); // vypíše "Ahoj, světe!\n" IText :: SPtr wHi ( nový CompositeText ); // slovo "Ahoj" wHi -> add ( lH ); whi -> přidat ( li ); věta . nahradit ( wHello , wHi ); věta . kreslit (); // vypíše "Ahoj, světe!"\n" věta . odstranit ( svět ); věta . odstranit ( lSpace ); věta . odstranit ( lComma ); věta . kreslit (); // vypíše "Ahoj!\n" návrat 0 ; }

Příklad v D

Zdrojový text v jazyce D import std . stdio ; abstract class TInfo { protected : string name ; public : void Info (); } class TFile : TInfo { protected : uint size ; public : this ( const string theName , uint theSize ) { name = the Name ; size = theSize ; } void Info () { writefln ( "%s\t%d" , jmeno , velikost ); } } class TDir : TInfo { protected : TInfo [] info ; public : this ( const string theName ) { name = the Name ; } void Info () { writefln ( "[%s]" , jmeno ); foreach ( f ; info ) { f . info (); } } void Přidat ( TInfo theInfo ) { info ~= theInfo ; } } void main () { TDir first = new TDir ( "first" ); první . Přidat ( nový soubor TF ( " a.txt " , 100 )); první . Přidat ( nový soubor TF ( " b.txt " , 200 )); první . Přidat ( nový soubor TF ( " c.txt " , 300 )); TDir druhý = nový TDir ( "druhý" ); druhý . Přidat ( nový soubor TF ( " d.txt " , 400 )); druhý . Přidat ( nový soubor TF ( " e.txt " , 500 )); TDir root = new TDir ( "root" ); kořen . Přidat ( první ); kořen . Přidat ( druhý ); kořen . info (); }

Příklad Pythonu

Zdrojový kód v Pythonu z abc import ABCMeta , abstraktní metoda class Unit ( metaclass = ABCMeta ): """ Abstraktní komponenta, v tomto případě se jedná o jednotku (jednotka se může skládat z jednoho nebo více vojáků) """ @abstractmethod def print ( self ) -> None : """ Tisk dat komponenty """ projít třída Lukostřelec ( Jednotka ): """ Lukostřelec """ def print ( self ) -> None : print ( 'archer' , end = ' ' ) třída Rytíř ( Jednotka ): """ Rytíř """ def print ( self ) -> None : print ( 'knight' , end = ' ' ) třída Šermíř ( Jednotka ): """ Šermíř """ def print ( self ) -> None : print ( 'šermíř' , end = ' ' ) class Squad ( Unit ): """ Spojovník je tým více než jedné osoby. Může také zahrnovat další spojovací týmy. """ def __init__ ( self ): self . _units = [] def print ( self ) -> None : print ( "Squad {} (" . format ( self . __hash__ ()), end = ' ' ) pro u v sobě . _units : u . print () print ( ')' ) def add ( self , unit : Unit ) -> None : """ Přidání nové jednotky :param unit: unit (může být buď základna nebo stavitel) """ self . _jednotky . připojit ( jednotku ) jednotku . tisknout () tisknout ( 'připojená k četě {} ' . formát ( vlastní . __hash__ ())) tisknout () def remove ( self , unit : Unit ) -> None : """ Odebrat jednotku z aktuálního stavitele :param unit: unit object """ for u in self . _units : if u == unit : self . _jednotky . odstranit ( u ) u . print () print ( 'left unit {} ' . format ( self . __hash__ ())) print () break else : unit . tisknout () tisknout ( 'nenalezeno v četě {} ' . formát ( self . __hash__ ())) tisknout () if __name__ == '__main__' : print ( 'OUTPUT:' ) squad = Squad () squad . přidat ( Knight ()) četa . přidat ( Knight ()) četa . přidat ( Lukostřelec ()) šermíř = Šermíř () četa . přidat ( šermíř ) četu . odstranit ( šermíř ) četa . print () squad_big = Squad () squad_big . přidat ( Swordsman ()) squad_big . přidat ( Swordsman ()) squad_big . přidat ( squad ) squad_big . tisknout () ''' VÝSTUP: Knight se připojil -9223363262492103834 rytíř se připojil k četě -9223363262492103834 lukostřelec se připojil k týmu -9223363262492103834 šermíř se připojil k týmu -9223363262492103834 šermíř opustil oddíl -9223363262492103834 Jednotka -9223363262492103834 (rytíř rytíř lukostřelec) šermíř se připojil k jednotě 8774362671992 šermíř vstoupil do oddílu 8774362671992 Družina -9223363262492103834 (rytíř rytíř lukostřelec) se připojil k četě 8774362671992 Squad 8774362671992 ( šermíř šermířská četa -9223363262492103834 ( rytíř rytíř lukostřelec ) ) '''

Příklad PHP5

Zdrojový kód PHP5 <?php abstract class Komponenta { protected $name ; public function __construct ( $name ) { $this -> name = $name ; } veřejné zobrazení abstraktní funkce (); } class Composite extends Komponenta { private $children = pole (); public function add ( Component $component ) { $this -> children [ $component -> name ] = $component ; } public function remove ( Component $component ) { unset ( $this -> children [ $component -> name ]); } public function display () { foreach ( $this -> děti jako $child ) { $child -> display (); } } } class Leaf extends Component { public function display () { print_r ( $this -> name ); } } // Vytvoření stromové struktury $root = new Composite ( "root" ); $root -> add ( new Leaf ( "List A" )); $root -> add ( new Leaf ( "List B" )); $comp = new Composite ( "CompositeX" ); $comp -> add ( nový list ( "List XA" )); $comp -> add ( new Leaf ( "List XB" )); $root -> add ( $comp ); $root -> add ( new Leaf ( "Leaf C" )); // Přidání a odebrání listu $leaf = new Leaf ( "Leaf D" ); $kořen -> přidat ( $list ); $kořen -> odstranit ( $list ); // Rekurzivně zobrazí strom $root -> display (); ?>

Příklad linkeru externího iterátoru PHP5

Zdrojový kód PHP5 /** * Vzor skladatele s externím iterátorem * Iterátor používá rekurzi k iteraci stromem prvků */ jmenný prostor compositeIterator { /** * Klient používá pro práci s objekty rozhraní AComponent. * Rozhraní AComponent definuje rozhraní pro všechny komponenty: jak kombinace, tak i koncové uzly. * AComponent může implementovat výchozí chování pro add() remove() getChild() a další operace */ abstract class AComponent { public $customPropertyName ; public $customPropertyDescription ; /** * @param AComponent $component */ public function add ( $component ) { throw new \Exception ( "Nepodporovaná operace" ); } /** * @param AComponent $component */ public function remove ( $component ) { throw new \Exception ( "Nepodporovaná operace" ); } /** * @param int $int */ public function getChild ( $int ) { throw new \Exception ( "Nepodporovaná operace" ); } /** * @return IPhpLikeIterator */ abstract function createIterator (); public function operation1 () { throw new \Exception ( "Nepodporovaná operace" ); } } /** * List zdědí metody add() remove() getChild(, což nemusí mít pro listový uzel smysl. * Ačkoli listový uzel lze považovat za uzel s nulovými potomky * * List definuje chování prvků kombinace . Za tímto účelem implementuje operace podporované složeným rozhraním */ class Leaf extends AComponent { public function __construct ( $name , $description = '' ) { $this -> customPropertyName = $name ; $this -> customPropertyDescription = $ popis ; } public function createIterator () { return new NullIterator (); } public function operation1 () { echo ( " \n Jsem list { $this -> customPropertyName } , nechci dělat operaci 1. { $this -> customPropertyDescription } " ); } } class NullIterator implementuje IPhpLikeIterator { public function valid () { return ( false ); } public function next () { return ( false ); } public function current () { return ( null ); } public function remove () { throw new \CException ( 'nepodporovaná operace' ); } } /** * Kompozitní rozhraní definuje chování komponent, které mají potomky, a poskytuje jim úložiště. * * Composite také implementuje operace související s listem. Některé z nich nemohou nedávat smysl pro kombinace; v takových případech je vyvolána výjimka. */ class Composite rozšiřuje AComponent { private $_iterator = null ; /** * @var \ArrayObject AComponent[] $components pro uložení potomků typu AComponent */ public $components = null ; public function __construct ( $name , $description = '' ) { $this -> customPropertyName = $name ; $this -> customPropertyDescription = $description ; } /** * @param AComponent $component */ public function add ( $component ) { if ( is_null ( $this -> komponenty )) { $this -> komponenty = new \ArrayObject ; } $this -> komponenty -> append ( $component ); } public function remove ( $component ) { foreach ( $this -> komponenty as $i => $c ) { if ( $c === $component ) { unset ( $this -> komponenty [ $i ]); } } } public function getChild ( $int ) { return ( $this -> komponenty [ $int ]); } public function operation1 () { echo " \n\n $this->customPropertyName $this->customPropertyDescription " ; echo " \n --------------------------------" ; $iterator = $this -> komponenty -> getIterator (); while ( $iterátor -> platný ()) { $komponenta = $iterátor -> aktuální (); $komponenta -> operace1 (); $iterator -> dalsi (); } } /** * @return CompositeIterator */ public function createIterator () { if ( is_null ( $this -> _iterator )) { $this -> _iterator = new CompositeIterator ( $this -> komponenty -> getIterator ()); } return ( $this -> _iterator ); } } /** * Rekurzivní složený iterátor */ class CompositeIterator implementuje IPhpLikeIterator { public $stack = pole (); /** * @param \ArrayIterator $componentsIterator */ public function __construct ( $componentsIterator ) { //$this->stack= new \ArrayObject; $this -> stack [] = $componentsIterator ; } public function remove () { throw new \CException ( 'nepodporovaná operace' ); } public function valid () { if ( empty ( $this -> stack )) { return ( false ); } else { /** @var $componentsIterator \ArrayIterator */ // získá první prvek $componentsIterator = array_shift ( array_values ​​​​( $this -> stack )); if ( $componentsIterator -> valid ()) { return ( true ); } else { array_shift ( $this -> stack ); return ( $this -> valid ()); } } } public function next () { /** @var $componentsIterator \ArrayIterator */ $componentsIterator = aktuální ( $this -> stack ); $component = $componentsIterator -> aktuální (); if ( $component instanceof Composite ) { array_push ( $this -> stack , $component -> createIterator ()); } $componentsIterator -> další (); //return($komponenta); } public function current () { if ( $this -> valid ()) { /** @var $componentsIterator \ArrayIterator */ // získání prvního prvku $componentsIterator = array_shift ( array_values ​​​​( $this -> stack )) ; return ( $componentsIterator -> aktuální ()); } else { return ( null ); } } } /** * Rozhraní iterátoru musí být implementováno všemi iterátory. * Toto rozhraní je součástí standardního rozhraní iterátoru php. * Konkrétní iterátor je zodpovědný za správu aktuální pozice iterace v konkrétní kolekci. */ interface IPhpLikeIterator { /** * @abstrakt * @return boolean je aktuální prvek */ public function valid (); /** * @abstrakt * @return smíšený přesun kurzoru dále */ public function next (); /** * @abstract * @return mixed získat aktuální prvek */ public function current (); /** * odstranění aktuálního prvku kolekce * @abstract * @return void */ public function remove (); } class Klient { /** * @varAComponent */ public $topItem ; public function __construct ( $topItem ) { $this -> topItem = $topItem ; } public function printOperation1 () { $this -> topItem -> operation1 (); } public function printOperation2 () { echo " \n\n\n " ; $iterator = $this -> topItem -> createIterator (); while ( $iterator -> valid ()) { /** @var $component AComponent */ $component = $iterator -> current (); if ( strstr ( $component -> customPropertyName , 'leaf1' )) { echo ( " \n Jsem klient, našel jsem list { $component -> customPropertyName } , nechám to zde (pro můj 'první- sbírka čajů z listů). { $component -> customPropertyDescription } " ); } $iterator -> dalsi (); } } } class Test { public static function go () { $a = new Composite ( "c1" ); $b = nový kompozit ( "c2" ); $c = nový kompozit ( "c3" ); $topItem = new Composite ( "top item" ); $topItem -> add ( $a ); $topItem -> add ( $b ); $topItem -> add ( $c ); $a -> add ( new Leaf ( "c1-leaf1" )); $a -> add ( new Leaf ( "c1-leaf2" )); $b -> add ( new Leaf ( "c2-leaf1" )); $b -> add ( new Leaf ( "c2-leaf2" )); $b -> add ( new Leaf ( "c2-leaf3" )); $c -> add ( new Leaf ( "c3-leaf1" )); $c -> add ( new Leaf ( "c3-leaf2" )); $klient = nový klient ( $topItem ); $klient -> tiskOperace1 (); $client -> printOperation2 (); } } test :: jít (); }

Příklad PHP5.4

Zdrojový text v PHP5.4 <?php rozhraní IComponent { funkce zobrazení (); } vlastnost TComponent { public $jméno ; public function __construct ( $name ) { $this -> name = $name ; } public function display () { print $this -> name . „<br>“ . PHP_EOL ; } } vlastnost TComposite { use TComponent { TComponent :: display as displaySelf ; } chráněno $children = pole (); public function add ( IComponent $item ) { $this -> children [ $item -> name ] = $item ; } public function remove ( IComponent $item ) { unset ( $this -> children [ $item -> name ]); } public function display () { $this -> displaySelf (); foreach ( $this -> děti jako $child ) { $child -> display (); } } } class Composite implementuje IComponent { use TComposite ; } class Leaf implementuje IComponent { use TComponent ; } $root = new Composite ( "root" ); $root -> add ( new Leaf ( "List A" )); $root -> add ( new Leaf ( "List B" )); $comp = new Composite ( "CompositeX" ); $comp -> add ( nový list ( "List XA" )); $comp -> add ( new Leaf ( "List XB" )); $root -> add ( $comp ); $root -> add ( new Leaf ( "Leaf C" )); $list = nový List ( "List D" ); $kořen -> přidat ( $list ); $kořen -> odstranit ( $list ); $root -> zobrazit ();

Příklad CoffeeScript

Zdrojový text v jazyce CoffeeScript

Příklad polotovaru jednoduchého fyzikálního enginu

# Třída komponenty PObject collide : (pObj) -> addChild : (pObj) -> rmChild : (index) -> getChild : (index) -> # Třída listu PShape extends PObject collide : (pObj) -> # ... # Složená třída PCollection rozšiřuje konstruktor PObject : -> @children = [] collide : (pObj) -> dítě . koliduje ( pObj ) pro dítě v @children return @ addChild : (pObj) -> @children . push ( pObj ) , pokud pObj instanceof PObject return @ rmChild : (index) -> @children . splice ( index , 1 ) return @ getChild : (index) -> @children [ index ]

Příklad VB.NET

Zdrojový text v jazyce VB.NET třídní program Sdílená podhlavní ( ) ' Vytvořte stromovou strukturu Dim root As Component = New Composite ( "root" ) kořen . Přidat ( Nový list ( "List A" )) kořen . Přidat ( nový list ( "list B" )) Dim comp jako komponenta = nový kompozit ( "Composite X" ) komp . Přidat ( Nový list ( "Leaf XA" ) ) komp . Přidat ( Nový list ( "Leaf XB" )) kořen . Přidat ( comp ) root . Přidat ( Nový list ( "List C" )) ' Přidejte a odeberte list Dim list As New Leaf ( "List D" ) kořen . Přidejte ( listový ) kořen . Odebrat ( list ) ' Rekurzivně zobrazit kořen stromu . Displej ( 1 ) ' Počkejte na uživatelskou konzoli . číst () End Sub End Class ''' <summary> ''' Komponenta - ''' </summary> ''' <li> ''' <lu>deklaruje rozhraní pro skládací objekty;</lu> ''' <lu>poskytuje vhodné výchozí operace implementace, ''' společné pro všechny třídy;</lu> ''' <lu>deklaruje rozhraní pro přístup a manipulaci s dětmi;</lu> ''' <lu>definuje rozhraní pro přístup k rodiči komponenty v rekurzivní strukturu ''' a volitelně ji implementuje. Tato funkce je volitelná;</lu> ''' </li> MustInherit Class Component Chráněné jméno As String ' Constructor Public Sub New ( ByVal name As String ) Me . jméno = jméno End Sub Public MustOverride Sub Add ( ByVal c As Component ) Public MustOverride Sub Remove ( ByVal c As Component ) Public MustOverride Sub Display ( ByVal hloubka As Integer ) End Class ''' <summary> ''' Kompozit – složený objekt ''' </summary> ''' <li> ''' <lu>definuje chování komponent, které mají potomky;</lu> ''' < lu >ukládá podřízené komponenty;</lu> ''' <lu>implementuje správu potomků a operace související s rozhraním ''' třídy <viz cref="Component"/></lu> ''' </li> Class Composite Zdědí soukromou podřízenou komponentu jako nový ArrayList () ' Constructor Public Sub New ( ByVal name As String ) MyBase . Nový ( název ) End Sub Veřejné přepíše Sub Add ( komponenta ByVal As Component ) potomky . Přidat ( komponenta ) End Sub Public Overrides Sub Remove ( ByVal component As Component ) potomků . Odebrat ( komponentu ) End Sub Public Overrides Sub Display ( ByVal depth As Integer ) Console . WriteLine ( nový řetězec ( "-"c , hloubka ) a název ) ' Rekurzivně zobrazit podřízené uzly pro každou komponentu jako komponentu v podřízené komponentě . Zobrazení ( hloubka + 2 ) Další konec Třída podtřídy _ ''' <summary> ''' List - list ''' </summary> ''' <remarks> ''' <li> ''' <lu>představuje listový uzel kompozice a nemá žádné potomky;< /lu> ''' <lu>definuje chování primitivních objektů v kompozici;</lu> ''' </li> ''' </remarks> Class Leaf zdědí komponentu ' Constructor Public Sub New ( ByVal name As String ) MyBase . Nový ( název ) End Sub Public Overrides Sub Add ( ByVal c As Component ) Console . WriteLine ( "Nelze přidat do listu" ) End Sub Public Overrides Sub Remove ( ByVal c As Component ) Console . WriteLine ( "Nelze odstranit z listu" ) End Sub Public Overrides Sub Display ( ByVal depth As Integer ) Console . WriteLine ( Nový řetězec ( "-"c , hloubka ) & název ) End Sub End Class

Příklad Delphi

Zdrojový text v Delphi program CompositePattern ; {$APPTYPE KONZOLE} používá SysUtils , Contnrs ; typ TCustomLetter = class public procedure Draw ; virtuální ; abstraktní ; konec ; type TLetter = class ( TCustomLetter ) private FLetter : Char ; veřejný konstruktor Create ( aLetter : Char ) ; postup Kreslit ; přepsat ; konec ; konstruktor TLetter . Create ( aLetter : Char ) ; begin FLetter := aLetter ; konec ; procedureTLetter _ _ kreslit ; begin Write ( FLetter ) ; konec ; typ TWord = class ( TCustomLetter ) private FWord : String ; veřejný konstruktor Create ( aWord : String ) ; postup Kreslit ; přepsat ; konec ; konstruktor TWord . Vytvořit ( aWord : String ) ; begin FWord := aWord ; konec ; postup TWord . kreslit ; begin Write ( FWord ) ; konec ; typ TText = class ( TCustomLetter ) private FList : TObjectList ; veřejný konstruktor Create ; destruktor Zničit ; přepsat ; procedure Add ( aCustomLetter : TCustomLetter ) ; postup Kreslit ; přepsat ; konec ; konstruktor TText . vytvořit ; začít zděděný ; FList := TObjectList . vytvořit ; konec ; destruktor TText . zničit ; začít FList . zdarma ; zděděný ; konec ; postup TText . Add ( aCustomLetter : TCustomLetter ) ; začít FList . Add ( aCustomLetter ) ; konec ; postup TText . kreslit ; var vI : Integer ; begin for vI := 0 to Pred ( FList . Count ) do TLetter ( FList [ vI ]) . kreslit ; konec ; var vRootText , vSubText : TText ; begin vRootText := TText . vytvořit ; vSubText := TText . vytvořit ; zkuste vSubText . Add ( TLetter . Create ( '!' )) ; vSubText . Add ( TLetter . Create ( '!' )) ; vSubText . Add ( TLetter . Create ( '!' )) ; vSubText . Add ( TWord . Create ( ' =)' )) ; vRootText . Přidat ( TLetter.Create ( ' H' ) ) ; vRootText . Přidat ( TLetter.Create ( ' E ' )) ; vRootText . Přidat ( TLetter.Create ( ' L' ) ) ; vRootText . Přidat ( TLetter.Create ( ' L' ) ) ; vRootText . Přidat ( TLetter.Create ( ' O' ) ) ; vRootText . Add ( TLetter . Create ( ' ' )) ; vRootText . Přidat ( TWord . Vytvořit ( 'Svět' )) ; vRootText . Přidat ( vSubText ) ; vRootText . kreslit ; konečně vRootText . zničit ; konec ; Readln ; konec .

Příklad JavaScriptu

Zdrojový kód JavaScriptu function Komponenta () { this . jméno = '' ; toto . hodnota = 0 ; toto . vykonat = funkce () { }; } function List ( jméno , hodnota ) { this . jmeno = jmeno ; toto . hodnota = hodnota ; toto . vykonat = funkce () { return this . hodnota ; }; } list . prototyp = Objekt . vytvořit ( Komponenta . prototyp ); list . prototyp . konstruktor = List ; function Composite ( name ) { var self = this ; var děti = []; toto . jmeno = jmeno ; toto . add = funkce ( komponenta ) { děti . tlačit ( komponent ); }; toto . remove = function ( ComponentName ) { var newChildren = []; děti . forEach ( function ( component ) { if ( component . name !== componentName ) { newChildren . push ( component ); } }); děti = novéDěti ; }; toto . vykonat = funkce () { děti . forEach ( funkce ( komponenta ) { vlastní . hodnota = ( vlastní . hodnota || 0 ) + komponenta . vykonat (); }); vrátit sebe . hodnota ; }; } Kompozitní . prototyp = Objekt . vytvořit ( Komponenta . prototyp ); Kompozitní . prototyp . konstruktor = Composite ; // Aplikace var kitchen = new Composite ( 'Kitchen' ); kuchyně . přidat ( nový list ( 'Horní sekce' , 5200 ) ); kuchyně . přidat ( nový list ( 'Horní dvojitá sekce' , 10000 ) )); kuchyně . add ( new Leaf ( 'Spodní sekce' , 4500 ) ) ); kuchyně . add ( new Leaf ( 'Sekce dolního rohu' , 7800 ) ) ); var vybavení = nový kompozit ( 'Zařízení' ); vybavení . přidat ( nový List ( 'Plynový sporák' , 26400 ) ); vybavení . přidat ( nový list ( 'Chladnička' , 32300 ) ) ); vybavení . add ( new Leaf ( 'Myčka nádobí' , 21600 ) ) ); kuchyně . přidat ( vybavení ); konzole . log ( 'Celkem: ' + kuchyně . vykonat () + ' RUB' );

Rychlý příklad

Rychlý zdrojový kód protokol položka { id var : UInt32 { získat } název var : String { získat } popis funkce () -> Řetězec } class Button : Item { id var : UInt32 = arc4random () název var : String = "Tlačítko" popis funkce () -> String { return "ID: \( id ) | \( jméno ) " } } class Label : Item { id var : UInt32 = arc4random () název var : String = "Label" popis funkce () -> String { return "ID: \( id ) | \( jméno ) " } } class View : Item { komponenty var : [ Item ] = [] id var : UInt32 = arc4random () název var : String = "Zobrazit" popis funkce () -> String { return komponenty . snížit ( "" , { " \( $0 ) \( $1 . popis ()) " }) } func add ( item : Item ) { komponenty . připojit ( položka ) } func remove ( item : Item ) { if let index = components . firstIndex ( kde : { $0 . id == item . id }) { komponenty . odebrat ( at : index ) } } } // Použijte kompozitní let button = Tlačítko () tisknout ( button.deskription ( ) ) let view = View () view . add ( item : Button ()) view . přidat ( položka : štítek ()) tisknout ( view.deskription ( ) )

Odkazy