Linker (designmönster)

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 9 maj 2016; kontroller kräver 16 redigeringar .
länk
Sammansatt
Sorts strukturell
Beskrivs i Design Patterns Ja

Kompositmönster är ett  strukturellt designmönster som kombinerar objekt till en trädstruktur för att representera en hierarki från det enskilda till helheten. Länkaren tillåter klienter att komma åt enskilda objekt och grupper av objekt på samma sätt.

Syfte

Mönstret definierar en hierarki av klasser som samtidigt kan bestå av primitiva och komplexa objekt, förenklar klientens arkitektur och gör processen att lägga till nya typer av objekt enklare.

Beskrivning

UML -diagrammall:

Implementeringsexempel

Java-exempel

Java-källa importera java.util.List ; importera java.util.ArrayList ; /** "Komponent" */ gränssnitt Grafik { //Skriver ut grafiken. public void print (); } /** "Composite" */ class CompositeGraphic implementerar Graphic { //Samling av barngrafik. privat lista < Graphic > mChildGraphics = new ArrayList < Graphic > (); //Skriver ut grafiken. public void print () { for ( Graphic graphic : mChildGraphics ) { graphic . print (); } } //Lägger till grafiken i kompositionen. public void add ( Graphic graphic ) { mChildGraphics . add ( grafik ); } //Tar bort grafiken från kompositionen. public void remove ( Graphic graphic ) { mChildGraphics . ta bort ( grafik ); } } /** "Löv" */ klass Ellips implementerar grafisk { //Skriver ut grafiken. public void print () { System . ut . println ( "Ellips" ); } } /** Klient */ offentlig klass Program { public static void main ( String [] args ) { //Initialisera fyra ellipser Ellipse ellips1 = new Ellipse (); Ellips ellips2 = ny Ellips (); Ellips ellips3 = ny Ellips (); Ellips ellips4 = ny Ellips (); //Initiera tre sammansatta grafik CompositeGraphic graphic = new CompositeGraphic (); CompositeGraphic graphic1 = new CompositeGraphic (); CompositeGraphic graphic2 = new CompositeGraphic (); //Komponerar grafikgrafiken1 . add ( ellips1 ); grafik 1 . add ( ellips2 ); grafik 1 . add ( ellips3 ); grafik 2 . add ( ellips4 ); grafik . add ( grafik1 ); grafik . add ( grafik2 ); //Skriver ut hela grafiken (fyra gånger strängen "Ellipse"). grafik . print (); } }

Exempel i C#

Källtext i C# class MainApp { static void Main () { // Skapa en trädstruktur Composite root = new Composite ( "root" ); rot . Lägg till ( nytt blad ( "Löv A" )); rot . Lägg till ( nytt blad ( "Löv B" )); Composite comp = new Composite ( "CompositeX" ); komp . Lägg till ( nytt blad ( "Löv XA" )); komp . Lägg till ( nytt blad ( "LeafXB" )); rot . Lägg till ( komp ); rot . Lägg till ( nytt blad ( "Löv C" )); // Lägg till och ta bort ett blad Leaf leaf = new Leaf ( "Leaf D" ); rot . Lägg till ( blad ); rot . Ta bort ( blad ); // Visa trädrot rekursivt . display ( 1 ); // Vänta på användarkonsolen . läs (); } } /// <sammanfattning> /// Komponent - komponent /// </summary> /// <li> /// <lu>deklarerar ett gränssnitt för komponerbara objekt;</lu> /// <lu>tillhandahåller en lämpliga implementeringsstandardoperationer, /// gemensamma för alla klasser;</lu> /// <lu>deklarerar ett gränssnitt för åtkomst och manipulering av barn;</lu> /// <lu>definierar ett gränssnitt för åtkomst till komponentens överordnade i en rekursiv struktur /// och implementerar den valfritt. Denna funktion är valfri;</lu> /// </li> abstrakt klass Komponent { protected string name ; // Constructor public Component ( strängnamn ) { this . namn = namn ; } offentlig abstrakt void Display ( int djup ); } /// <summary> /// Composite - ett sammansatt objekt /// </summary> /// <li> /// <lu>definierar beteendet hos komponenter som har barn;</lu> /// < lu >lagrar underordnade komponenter;</lu> /// <lu>implementerar operationer relaterade till underordnad hantering och gränssnitt /// av klassen <see cref="Component"/></lu> /// </li > Composite : Component { privat lista < Komponent > barn = ny lista < Komponent >(); // Constructor public Composite ( strängnamn ) : bas ( namn ) { } public void Lägg till ( komponentkomponent ) { barn . Lägg till ( komponent ); } public void Ta bort ( komponentkomponent ) { barn . Ta bort ( komponent ); } public override void Display ( int djup ) { Console . WriteLine ( ny sträng ( '-' , djup ) + namn ); // Rekursiv visa underordnade noder foreach ( komponentkomponent i barn ) { komponent . Display ( djup + 2 ); } } } /// <sammanfattning> /// Löv - blad /// </summary> /// <remarks> /// <li> /// <lu>representerar kompositionens bladnod och har inga barn;< /lu> /// <lu>definierar beteendet hos primitiva objekt i kompositionen;</lu> /// </li> /// </remarks> class Leaf : Component { // Constructor public Leaf ( strängnamn ) : bas ( namn ) { } public override void Display ( int djup ) { Console . WriteLine ( ny sträng ( '-' , djup ) + namn ); } }

C++ exempel

Källtext i C++ #include <iostream> #inkludera <lista> #inkludera <algoritm> #inkludera <minne> klass IText { offentliga : typedef std :: shared_ptr < IText > SPtr ; virtuell void draw () = 0 ; virtual void add ( const SPtr & ) { throw std :: runtime_error ( "IText: Kan inte lägga till ett blad" ); } virtual void remove ( const SPtr & ){ throw std :: runtime_error ( "IText: Kan inte ta bort från ett blad" ); } }; class CompositeText : public IText { offentliga : void add ( const SPtr & sptr ){ barn_ . push_back ( sptr ); } void remove ( const SPtr & sptr ){ barn_ . ta bort ( sptr ); } void replace ( const SPtr & oldValue , const SPtr & newValue ){ std :: replace ( children_ . begin (), children_ . end (), oldValue , newValue ); } virtuell void draw (){ för ( SPtr & sptr : barn_ ){ sptr -> rita (); } } privat : std :: lista < SPtr > barn_ ; }; class Letter : public IText { offentliga : Bokstav ( char c ) : c_ ( c ) {} virtuell void draw (){ std :: cout << c_ ; } privat : char c_ ; }; int main (){ CompositeText mening ; IText :: SPtr lSpace ( ny bokstav ( ' ' )); IText :: SPtr lExcl ( ny bokstav ( '!' )); IText :: SPtr lComma ( ny bokstav ( ',' )); IText :: SPtr lNewLine ( ny bokstav ( '\n' )); IText :: SPtr lH ( ny bokstav ( 'H' )); // bokstaven 'H' IText :: SPtr le ( ny bokstav ( 'e' )); // bokstaven 'e' IText :: SPtr ll ( ny bokstav ( 'l' )); // bokstaven 'l' IText :: SPtr lo ( ny bokstav ( 'o' )); // bokstaven 'o' IText :: SPtr lW ( ny bokstav ( 'W' )); // bokstaven 'W' IText :: SPtr lr ( ny bokstav ( 'r' )); // bokstaven 'r' IText :: SPtr ld ( ny bokstav ( 'd' )); // bokstaven 'd' IText :: SPtr li ( ny bokstav ( 'i' )); // bokstaven 'i' IText :: SPtr wHello ( ny CompositeText ); wHello -> lägg till ( lH ); wHello -> lägg till ( le ); wHello -> lägg till ( ll ); wHello -> lägg till ( ll ); wHello -> lägg till ( lo ); IText :: SPtr wWorld ( ny CompositeText ); // ordet "World" wWorld -> add ( lW ); wWorld -> lägg till ( lo ); wWorld -> lägg till ( lr ); wWorld -> lägg till ( ll ); wWorld -> lägg till ( ld ); mening . add ( wHello ); mening . add ( lComma ); mening . add ( lSpace ); mening . add ( wWorld ); mening . add ( lExcl ); mening . add ( lNewLine ); mening . rita (); // skriver ut "Hej världen!\n" IText :: SPtr wHi ( ny CompositeText ); // ordet "Hej" wHi -> lägg till ( lH ); whi -> lägg till ( li ); mening . replace ( wHello , wHi ); mening . rita (); // skriver ut "Hej världen!\n" mening . ta bort ( wWorld ); mening . ta bort ( lSpace ); mening . ta bort ( lComma ); mening . rita (); // skriver ut "Hej!\n" returnera 0 ; }

Exempel i D

Källtext på D-språk import std . stdio ; abstrakt klass TInfo { skyddad : strängnamn ; _ public : void Info (); } class TFile : TInfo { protected : uint size ; public : this ( const string theName , uint theSize ) { name = theName ; storlek = storleken ; } void Info () { writefln ( "%s\t%d" , namn , storlek ); } } klass TDir : TInfo { skyddad : TInfo [] info ; public : this ( const string theName ) { name = theName ; } void Info () { writefln ( "[%s]" , namn ); foreach ( f ; info ) { f . info (); } } void Lägg till ( TInfo theInfo ) { info ~= theInfo ; } } void main () { TDir första = ny TDir ( "första" ); först . Lägg till ( ny TF-fil ( "a.txt" , 100 )); först . Lägg till ( ny TFile ( "b.txt" , 200 )); först . Lägg till ( ny TFile ( "c.txt" , 300 )); TDir andra = ny TDir ( "andra" ); andra . Lägg till ( ny TFile ( "d.txt" , 400 )); andra . Lägg till ( ny TFile ( "e.txt" , 500 )); TDir rot = ny TDir ( "rot" ); rot . Lägg till ( först ); rot . Lägg till ( andra ); rot . info (); }

Python-exempel

Källkod i Python från abc import ABCMeta , abstraktmetod class Unit ( metaclass = ABCMeta ): """ En abstrakt komponent, i detta fall är det en enhet (en enhet kan bestå av en eller flera soldater) """ @abstractmethod def print ( self ) -> None : """ Skriv ut komponentdata """ pass klass Archer ( Enhet ): """ Archer """ def print ( self ) -> None : print ( 'archer' , end = ' ' ) klass Riddare ( Enhet ): """ Riddare """ def print ( self ) -> None : print ( 'knight' , end = ' ' ) klass Swordsman ( Enhet ): """ Swordsman """ def print ( self ) -> None : print ( 'swordsman' , end = ' ' ) class Squad ( Enhet ): """ En länkgrupp är en grupp med mer än en person. Kan även inkludera andra länkgrupper. """ def __init__ ( själv ): själv . _enheter = [] def print ( self ) -> None : print ( "Squad {} (" . format ( self . __hash__ ()), end = ' ' ) för u in self . _units : u . print () print ( ')' ) def add ( self , unit : Unit ) -> None : """ Lägga till en ny enhet :param unit: unit (kan vara antingen bas eller byggare) """ self . _enheter . lägga till ( enhet ) enhet . print () print ( 'joined squad {} ' . format ( self . __hash__ ())) print () def remove ( self , unit : Unit ) -> None : """ Ta bort enhet från nuvarande byggare :param unit: unit object """ för u in self . _enheter : om u == enhet : själv . _enheter . ta bort ( u ) u . print () print ( 'left unit {} ' . format ( self . __hash__ ())) print () break else : unit . print () print ( 'hittades inte i squad {} ' . format ( self . __hash__ ())) print () om __name__ == '__main__' : print ( 'OUTPUT:' ) squad = Squad () squad . lägg till ( Knight ()) trupp . lägg till ( Knight ()) trupp . add ( Archer ()) swordsman = Swordsman () squad . lägga till ( svärdsman ) trupp . ta bort ( svärdsman ) trupp . print () squad_big = Squad () squad_big . lägg till ( Swordsman ()) squad_big . lägg till ( Swordsman ()) squad_big . add ( squad ) squad_big . skriv ut () ''' UTGÅNG: Knight har gått med -9223363262492103834 riddare gick med i truppen -9223363262492103834 bågskytt gick med i truppen -9223363262492103834 svärdfäktare gick med i truppen -9223363262492103834 svärdsmannen lämnade truppen -9223363262492103834 Squad -9223363262492103834 (knight knight archer) swordsman gick med i squad 8774362671992 svärdfäktare gick med i truppen 8774362671992 Squad -9223363262492103834 (ridder riddare bågskytt) gick med i truppen 8774362671992 Squad 8774362671992 ( swordsman swordsman Squad -9223363262492103834 ( knight knight archer ) ) '''

PHP5 exempel

PHP5 källkod <?php abstrakt klass Komponent { protected $name ; offentlig funktion __construct ( $name ) { $this -> name = $name ; } offentlig abstrakt funktion display (); } class Composite utökar Component { private $children = array (); public function add ( Komponent $component ) { $this -> children [ $component -> name ] = $component ; } public function remove ( Component $component ) { unset ( $this -> children [ $component -> name ]); } public function display () { foreach ( $this -> children as $child ) { $child -> display (); } } } class Leaf utökar Component { public function display () { print_r ( $this -> name ); } } // Skapa en trädstruktur $root = new Composite ( "root" ); $root -> add ( nytt Leaf ( "Löv A" )); $root -> add ( nytt blad ( "Löv B" )); $comp = new Composite ( "CompositeX" ); $comp -> add ( nytt Leaf ( "Leaf XA" )); $comp -> add ( nytt Leaf ( "Leaf XB" )); $root -> add ( $comp ); $root -> add ( nytt Leaf ( "Leaf C" )); // Lägg till och ta bort ett blad $leaf = new Leaf ( "Leaf D" ); $root -> add ( $leaf ); $root -> remove ( $leaf ); // Rekursivt visa trädet $root -> display (); ?>

PHP5 extern iterator länkexempel

PHP5 källkod /** * Kompositörsmönster med extern iterator * Iteratorn använder rekursion för att iterera genom elementträdet */ namespace compositeIterator { /** * Klienten använder AComponent-gränssnittet för att arbeta med objekt. * AComponent-gränssnittet definierar gränssnittet för alla komponenter: både kombinationer och bladnoder. * AComponent kan implementera standardbeteende för add() remove() getChild() och andra operationer */ abstrakt klass AComponent { public $customPropertyName ; public $customPropertyDescription ; /** * @param AComponent $component */ public function add ( $component ) { throw new \Exception ( "Ostödd operation" ); } /** * @param AComponent $component */ public function remove ( $component ) { throw new \Exception ( "Ostödd operation" ); } /** * @param int $int */ offentlig funktion getChild ( $int ) { throw new \Exception ( "Ostödd operation" ); } /** * @return IPhpLikeIterator */ abstrakt funktion createIterator (); public function operation1 () { throw new \Exception ( "Operation som inte stöds" ); } } /** * Leaf ärver add() remove() getChild(-metoderna, vilket kanske inte är meningsfullt för en lövnod. * Även om en lövnod kan betraktas som en nod med noll underordnade * * Leaf definierar beteendet hos kombinationselementen För att göra detta implementerar den operationerna som stöds av Composite-gränssnittet */ class Leaf utökar AComponent { public function __construct ( $name , $description = '' ) { $this -> customPropertyName = $name ; $this -> customPropertyDescription = $ beskrivning ; } offentlig funktion createIterator () { returnera ny NullIterator (); } public function operation1 () { echo ( " \n Jag är leaf { $this -> customPropertyName } , jag vill inte göra operation 1. { $this -> customPropertyDescription } " ); } } class NullIterator implementerar IPhpLikeIterator { public function valid () { return ( false ); } public function next () { return ( false ); } public function current () { return ( null ); } public function remove () { throw new \CException ( 'operation som inte stöds' ); } } /** * Det sammansatta gränssnittet definierar beteendet hos komponenter som har barn och tillhandahåller lagring åt dem. * * The Composite implementerar också Leaf-relaterade operationer. Vissa av dem kan inte undgå att vara vettiga för kombinationer; i sådana fall görs ett undantag. */ class Composite utökar AComponent { privat $_iterator = null ; /** * @var \ArrayObject AComponent[] $komponenter för att lagra barn av typen AComponent */ public $components = null ; offentlig funktion __construct ( $name , $description = '' ) { $this -> customPropertyName = $name ; $this -> customPropertyDescription = $description ; } /** * @param AComponent $component */ public function add ( $component ) { if ( is_null ( $this -> komponenter )) { $this -> komponenter = new \ArrayObject ; } $this -> komponenter -> append ( $component ); } public function remove ( $component ) { foreach ( $this -> komponenter som $i => $c ) { if ( $c === $component ) { unset ( $this -> komponenter [ $i ]); } } } public function getChild ( $int ) { return ( $this -> komponenter [ $int ]); } public function operation1 () { echo " \n\n $this->customPropertyName $this->customPropertyDescription " ; echo " \n ----------------------------------------" ; $iterator = $this -> komponenter -> getIterator (); while ( $iterator -> giltig ()) { $component = $iterator -> aktuell (); $component -> operation1 (); $iterator -> nästa (); } } /** * @return CompositeIterator */ public function createIterator () { if ( is_null ( $this -> _iterator )) { $this -> _iterator = new CompositeIterator ( $this -> komponenter -> getIterator ()); } return ( $this -> _iterator ); } } /** * Rekursiv sammansatt Iterator */ klass CompositeIterator implementerar IPhpLikeIterator { public $stack = array (); /** * @param \ArrayIterator $componentsIterator */ offentlig funktion __construct ( $componentsIterator ) { //$this->stack= new \ArrayObject; $this -> stack [] = $componentsIterator ; } public function remove () { throw new \CException ( 'operation som inte stöds' ); } public function valid () { if ( tom ( $this -> stack )) { return ( false ); } else { /** @var $componentsIterator \ArrayIterator */ // få det första elementet $componentsIterator = array_shift ( array_values ​​( $this -> stack )); if ( $componentsIterator -> giltig ()) { return ( true ); } else { array_shift ( $this -> stack ); return ( $this -> giltig ()); } } } public function next () { /** @var $componentsIterator \ArrayIterator */ $componentsIterator = aktuell ( $this -> stack ); $component = $componentsIterator -> aktuell (); if ( $component instans av Composite ) { array_push ( $this -> stack , $component -> createIterator ()); } $componentsIterator -> nästa (); //retur($komponent); } public function current () { if ( $this -> valid ()) { /** @var $componentsIterator \ArrayIterator */ // få det första elementet $componentsIterator = array_shift ( array_values ​( $this -> stack )) ; return ( $componentsIterator -> aktuell ()); } else { return ( null ); } } } /** * Iterator-gränssnittet måste implementeras av alla iteratorer. * Detta gränssnitt är en del av standardgränssnittet för php iterator. * En viss Iterator är ansvarig för att hantera den aktuella iterationspositionen i en viss samling. */ interface IPhpLikeIterator { /** * @abstract * @return boolean är det aktuella elementet */ public function valid (); /** * @abstract * @return blandad flytta markören vidare */ offentlig funktion nästa (); /** * @abstract * @return mixed få det aktuella elementet */ public function current (); /** * ta bort det aktuella elementet i samlingen * @abstract * @return void */ public function remove (); } class Client { /** * @varAComponent */ public $topItem ; offentlig funktion __construct ( $topItem ) { $this -> topItem = $topItem ; } public function printOperation1 () { $this -> topItem -> operation1 (); } public function printOperation2 () { echo " \n\n\n " ; $iterator = $this -> topItem -> createIterator (); while ( $iterator -> giltig ()) { /** @var $component AComponent */ $component = $iterator -> aktuell (); if ( strstr ( $component -> customPropertyName , 'leaf1' )) { echo ( " \n Jag är klient, jag hittade leaf { $component -> customPropertyName } , jag lämnar det här (för min 'första-) leafs tesamling ). { $component -> customPropertyDescription } " ); } $iterator -> nästa (); } } } class Test { public static function go () { $a = new Composite ( "c1" ); $b = ny sammansatt ( "c2" ); $c = ny sammansatt ( "c3" ); $topItem = ny sammansatt ( "top item" ); $topItem -> lägg till ( $a ); $topItem -> lägg till ( $b ); $topItem -> lägg till ( $c ); $a -> add ( nytt blad ( "c1-blad1" )); $a -> add ( nytt blad ( "c1-blad2" )); $b -> add ( nytt blad ( "c2-blad1" )); $b -> add ( nytt blad ( "c2-blad2" )); $b -> add ( nytt blad ( "c2-blad3" )); $c -> add ( nytt blad ( "c3-blad1" )); $c -> add ( nytt blad ( "c3-blad2" )); $client = ny klient ( $topItem ); $client -> printOperation1 (); $client -> printOperation2 (); } } test :: (); }

PHP5.4 exempel

Källtext i PHP5.4 <?php gränssnitt IComponent { funktionsdisplay ( ); } egenskap TComponent { public $name ; offentlig funktion __construct ( $name ) { $this -> name = $name ; } public function display () { print $this -> name . '<br>' . PHP_EOL ; } } trait TComposite { use TComponent { TComponent :: display as displaySelf ; } skyddade $barn = array (); 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 -> children as $child ) { $child -> display (); } } } class Composite implementerar IComponent { use TComposite ; } class Leaf implementerar IComponent { use TComponent ; } $root = ny sammansatt ( "root" ); $root -> add ( nytt Leaf ( "Löv A" )); $root -> add ( nytt blad ( "Löv B" )); $comp = new Composite ( "CompositeX" ); $comp -> add ( nytt Leaf ( "Leaf XA" )); $comp -> add ( nytt Leaf ( "Leaf XB" )); $root -> add ( $comp ); $root -> add ( nytt Leaf ( "Leaf C" )); $leaf = new Leaf ( "Löv D" ); $root -> add ( $leaf ); $root -> remove ( $leaf ); $root -> display ();

CoffeeScript- exempel

Källtext på CoffeeScript-språket

Ett exempel på en blank av en enkel fysikmotor

# Komponentklass PObject collide : (pObj) -> addChild : (pObj) -> rmChild : (index) -> getChild : (index) -> # Lövklass PShape förlänger PObject collide : (pObj) -> # ... # Sammansatt klass PCollection utökar PObject- konstruktorn: -> @children = [] kollidera : (pObj) -> barn . kollidera ( pObj ) för barn i @children return @ addChild : (pObj) -> @children . push ( pObj ) om pObj- instansen av PObject returnerar @ rmChild : (index) -> @children . skarva ( index , 1 ) return @ getChild : (index) -> @children [ index ]

VB.NET exempel

Källtext på språket VB.NET klassprogram _ Delad SubMain ( ) ' Skapa en trädstruktur Dim root As Component = New Composite ( "root" ) rot . Lägg till ( New Leaf ( "Löv A" )) rot . Lägg till ( Nytt blad ( "Löv B" )) Dim comp As Component = New Composite ( "Composite X" ) komp . Lägg till ( New Leaf ( "Leaf XA" ) ) komp . Lägg till ( New Leaf ( "Leaf XB" ) ) rot . Lägg till ( komp ) rot . Lägg till ( Nytt blad ( "Löv C" )) ' Lägg till och ta bort ett blad Dim leaf As New Leaf ( "Löv D" ) rot . Lägg till ( blad ) rot . Ta bort ( blad ) 'Visa trädrot rekursivt . Display ( 1 ) " Vänta på användarkonsolen . läs () Slut Sub Slutklass _ ''' <summary> ''' Komponent - ''' </summary> ''' <li> ''' <lu>deklarerar ett gränssnitt för komponerbara objekt;</lu> ''' <lu>tillhandahåller en lämplig implementeringsstandardoperationer, ''' gemensamma för alla klasser;</lu> ''' <lu>deklarerar ett gränssnitt för åtkomst och manipulering av barn;</lu> ''' <lu>definierar ett gränssnitt för åtkomst till en komponents förälder i en rekursiv struktur ''' och implementerar den valfritt. Denna funktion är valfri;</lu> ''' </li> MustInherit Class Component Protected name As String ' Constructor Public Sub New ( ByVal name As String ) Me . namn = namn End Sub Public MustOverride Sub Add ( ByVal c As Component ) Public MustOverride Sub Remove ( ByVal c As Component ) Public MustOverride Sub Display ( ByVal djup som heltal ) Slutklass _ ''' <summary> ''' Composite - ett sammansatt objekt ''' </summary> ''' <li> ''' <lu>definierar beteendet hos komponenter som har barn;</lu> ''' < lu >lagrar underordnade komponenter;</lu> ''' <lu>implementerar underordnade hantering och gränssnittsrelaterade operationer ''' för klass <see cref="Component"/></lu> ''' </li> Class Composite Ärver komponent privata barn som ny ArrayList () ' Constructor Public Sub New ( ByVal name As String ) MyBase . Nytt ( namn ) End Sub Public Overrides Sub Add ( ByVal component As Component ) barn . Lägg till ( komponent ) End Sub Public Overrides Sub Ta bort ( ByVal- komponent som komponent ) barn . Ta bort ( komponent ) End Sub Offentlig åsidosättning undervisning ( ByVal djup som heltal ) konsol . _ WriteLine ( Ny sträng ( "-"c , djup ) & namn ) ' Rekursivt visa underordnade noder för varje komponent som komponent i underordnad komponent . Display ( djup + 2 ) Next End Sub End Class ''' <summary> ''' Löv - blad ''' </summary> ''' <remarks> ''' <li> ''' <lu>representerar kompositionens bladnod och har inga barn;< /lu> ''' <lu>definierar beteendet hos primitiva objekt i kompositionen;</lu> ''' </li> ''' </remarks > Klassblad ärver komponent ' Constructor Public Sub New ( ByVal name As String ) MyBase . Nytt ( namn ) End Sub Public Overrides Sub Add ( ByVal c As Component ) Console . WriteLine ( "Kan inte lägga till i ett blad" ) End Sub Public Overrides Sub Remove ( ByVal c As Component ) Console . WriteLine ( "Kan inte ta bort från ett blad" ) End Sub Offentlig åsidosättning undervisning ( ByVal djup som heltal ) konsol . _ WriteLine ( Ny sträng ( "-"c , djup ) & namn ) End Sub End Class

Delphi exempel

Källtext i Delphi program CompositePattern ; {$APPTYPE KONSOL} använder SysUtils , Contnrs ; typ TCustomLetter = klass offentligt förfarande Draw ; virtuell ; abstrakt ; slut ; typ TLetter = klass ( TCustomLetter ) privat FLetter : Char ; offentlig konstruktör Skapa ( aLetter : Char ) ; procedur Rita ; åsidosätta ; slut ; konstruktör TLetter . Skapa ( aLetter : Char ) ; börja FLetter := aLetter ; slut ; procedurLetter . _ rita ; börja Skriv ( FLetter ) ; slut ; typ TWord = klass ( TCustomLetter ) privat FWord : String ; public constructor Skapa ( aWord : String ) ; procedur Rita ; åsidosätta ; slut ; konstruktör TWord . Skapa ( aWord : String ) ; börja FWord := aWord ; slut ; procedur TWord . rita ; börja Skriv ( FWord ) ; slut ; typ TText = klass ( TCustomLetter ) privat FList : TObjectList ; offentlig konstruktör Skapa ; förstörare Destroy ; åsidosätta ; procedur Lägg till ( aCustomLetter : TCustomLetter ) ; procedur Rita ; åsidosätta ; slut ; konstruktör TText . skapa ; börja ärvt ; FList := TObjectList . skapa ; slut ; destructor TText . Förstöra ; börja FList . Gratis ; ärvt ; slut ; procedur TText . Lägg till ( aCustomLetter : TCustomLetter ) ; börja FList . Lägg till ( aCustomLetter ) ; slut ; procedur TText . rita ; var vI : Heltal ; börja för vI := 0 till Pred ( FList . Count ) gör TLetter ( FList [ vI ]) . rita ; slut ; var vRootText , vSubText : TText ; börja vRootText := TText . skapa ; vSubText := TText . skapa ; prova vSubText . Lägg till ( TLetter . Skapa ( '!' )) ; vSubText . Lägg till ( TLetter . Skapa ( '!' )) ; vSubText . Lägg till ( TLetter . Skapa ( '!' )) ; vSubText . Lägg till ( TWord . Skapa ( ' =)' )) ; vRootText . Lägg till ( TLetter.Create ( ' H' ) ) ; vRootText . Lägg till ( TLetter.Create ( ' E ' )) ; vRootText . Lägg till ( TLetter.Create ( ' L' ) ) ; vRootText . Lägg till ( TLetter.Create ( ' L' ) ) ; vRootText . Lägg till ( TLetter.Create ( ' O' ) ) ; vRootText . Lägg till ( TLetter . Skapa ( '' )) ; vRootText . Lägg till ( TWord . Skapa ( 'World' )) ; vRootText . Lägg till ( vSubText ) ; vRootText . rita ; slutligen vRootText . Förstöra ; slut ; Läsln ; slut .

JavaScript- exempel

JavaScript-källkod function Component () { this . namn = '' ; detta . värde = 0 ; detta . execute = funktion () { }; } function Leaf ( namn , värde ) { detta . namn = namn ; detta . värde = värde ; detta . execute = function () { returnera detta . värde ; }; } blad . prototyp = Objekt . skapa ( Komponent . prototyp ); blad . prototyp . konstruktor = Blad ; function Composite ( namn ) { var self = this ; var barn = []; detta . namn = namn ; detta . add = funktion ( komponent ) { barn . push ( komponent ); }; detta . remove = function ( componentName ) { var newChildren = []; barn . forEach ( function ( komponent ) { if ( komponent . namn !== komponentnamn ) { newChildren . push ( komponent ); } }); barn = nyaBarn ; }; detta . execute = function () { barn . forEach ( funktion ( komponent ) { själv . värde = ( själv . värde || 0 ) + komponent . exekvera (); }); återvända själv . värde ; }; } Komposit . prototyp = Objekt . skapa ( Komponent . prototyp ); Komposit . prototyp . konstruktor = Sammansatt ; // Application var kitchen = new Composite ( 'Kök' ); kök . add ( nytt blad ( 'Överst avsnitt' , 5200 ) ); kök . add ( nytt blad ( 'Top Double Section' , 10000 ) ); kök . add ( nytt blad ( 'Lower Section' , 4500 ) ); kök . add ( nytt blad ( 'Nedre hörnsektion' , 7800 ) ); var equipment = new Composite ( 'Equipment' ); utrustning . add ( nytt Leaf ( 'Gasspis' , 26400 ) ); utrustning . add ( nytt blad ( 'Kylskåp' , 32300 ) ); utrustning . add ( nytt blad ( 'Diskmaskin' , 21600 ) ); kök . lägga till ( utrustning ); konsol . log ( 'Totalt: ' + kök . exekvera () + ' RUB' );

Snabbexempel

Swift källkod protokoll Artikel { var id : UInt32 { get } var name : String { get } funk beskrivning () -> String } class Button : Artikel { var id : UInt32 = arc4random () var name : String = "Button" func desctiption () -> String { return "ID: \( id ) | \( name ) " } } klassetikett : Artikel { _ var id : UInt32 = arc4random () var name : String = "Etikett" func desctiption () -> String { return "ID: \( id ) | \( name ) " } } klassvy : Objekt { _ var komponenter : [ Artikel ] = [] var id : UInt32 = arc4random () var name : String = "Visa" func desctiption () -> String { return komponenter . reducera ( "" , { " \( $0 ) \( $1 . desctiption ()) " }) } func add ( artikel : Artikel ) { komponenter . lägga till ( objekt ) } func remove ( objekt : Objekt ) { if let index = komponenter . firstIndex ( där : { $0 . id == item . id }) { komponenter . ta bort ( vid : index ) } } } // Använd komposit let button = Button () print ( button.desctiption ( ) ) let view = View () view . lägg till ( objekt : Knapp ()) vy . lägg till ( objekt : Etikett ()) skriv ut ( view.dectiption ( ) )

Länkar