Linkkeri (suunnittelukuvio)
Kokeneet kirjoittajat eivät ole vielä tarkistaneet sivun nykyistä versiota, ja se voi poiketa merkittävästi 9. toukokuuta 2016 tarkistetusta
versiosta . tarkastukset vaativat
16 muokkausta .
Yhdistelmäkuvio on rakenteellinen suunnittelukuvio , joka yhdistää objektit puurakenteeksi edustamaan hierarkiaa yksittäisestä kokonaisuuteen. Linkkerin avulla asiakkaat voivat käyttää yksittäisiä objekteja ja objektiryhmiä samalla tavalla.
Tarkoitus
Malli määrittelee luokkien hierarkian, joka voi koostua samanaikaisesti primitiivisistä ja monimutkaisista objekteista, yksinkertaistaa asiakkaan arkkitehtuuria ja helpottaa uudentyyppisten objektien lisäämistä.
Kuvaus
UML- kaaviomalli:
Toteutusesimerkkejä
Java-esimerkki
Java lähde
tuonti java.util.List ;
tuonti java.util.ArrayList ;
/** "Komponentti" */
käyttöliittymä Graphic {
//Tulostaa grafiikan.
julkinen tyhjä printti ();
}
/** "Composite" */
luokka CompositeGraphic toteuttaa grafiikan {
//Kokoelma lapsigrafiikkaa.
yksityinen luettelo < Grafiikka > mChildGraphics = uusi ArrayList < Graphic > ();
//Tulostaa grafiikan.
public void print () {
for ( Graafinen grafiikka : mChildGraphics ) {
graphic . tulostaa ();
}
}
//Lisää grafiikan koostumukseen.
public void add ( Graafinen grafiikka ) {
mChildGraphics . lisää ( grafiikka );
}
//Poistaa grafiikan koostumuksesta.
public void remove ( Graphic graphic ) {
mChildGraphics . poistaa ( grafiikka );
}
}
/** "Leaf" */
luokka Ellipsi toteuttaa grafiikan {
//Tulostaa grafiikan.
public void print () {
Järjestelmä . ulos . println ( "Ellipsi" );
}
}
/** Asiakas *
/ julkinen luokkaohjelma {
public static void main ( String [] args ) {
//Alusta neljä ellipsiä
Ellipsi ellipsi1 = uusi ellipsi ();
Ellipsi ellipsi2 = uusi ellipsi ();
Ellipsi ellipsi3 = uusi ellipsi ();
Ellipsi ellipsi4 = uusi ellipsi ();
//Alusta kolme yhdistelmägrafiikkaa
CompositeGraphic graphic = uusi CompositeGraphic ();
CompositeGraphic graphic1 = uusi CompositeGraphic ();
CompositeGraphic graphic2 = uusi CompositeGraphic ();
//Säveltää grafiikan
grafiikan1 . lisää ( ellipsi1 );
graafinen 1 . lisää ( ellipsi2 );
graafinen 1 . lisää ( ellipsi3 );
graafinen 2 . lisää ( ellipsi4 );
graafinen . lisää ( grafiikka1 );
graafinen . lisää ( grafiikka2 );
//Tulostaa koko grafiikan (neljä kertaa merkkijono "Ellipsi").
graafinen . tulostaa ();
}
}
Esimerkki C#:ssa
Lähdeteksti C#
class MainApp
{
static void Main ()
{
// Luo puurakenne
Yhdistelmäjuuri = new Komposiitti ( " juuri " );
juuri . Lisää ( uusi lehti ( "Leaf A" ));
juuri . Lisää ( uusi lehti ( "Lehti B" ));
Composite comp = uusi komposiitti ( "CompositeX" );
comp . Lisää ( new Leaf ( "Leaf XA" ));
comp . Lisää ( new Leaf ( "LeafXB" ));
juuri . Lisää ( comp );
juuri . Lisää ( new Leaf ( "Leaf C" ));
// Lisää ja poista lehti
Leaf leaf = uusi lehti ( "Leaf D" );
juuri . Lisää ( lehti );
juuri . Poista ( lehti );
// Näytä puun
juuri rekursiivisesti . näyttö ( 1 );
// Odota käyttäjän
konsolia . lue ();
}
}
/// <summary>
/// Komponentti - komponentti
/// </summary>
/// <li>
/// <lu>ilmoittaa liitännän kootettaville objekteille;</lu>
/// <lu>tarjoaa sopivat toteutuksen oletusoperaatiot,
/// yhteiset kaikille luokille;</lu>
/// <lu>ilmoittaa rajapinnan lapsiin pääsyä ja manipulointia varten;</lu>
/// <lu>määrittää käyttöliittymän komponentin ylätason käyttämiseen rekursiivisessa rakenteessa
/// ja toteuttaa sen valinnaisesti. Tämä ominaisuus on valinnainen;</lu>
/// </li>
abstrakti class Komponentti
{
suojatun merkkijonon nimi ;
// Rakentaja
public Component ( merkkijonon nimi )
{
this . nimi = nimi ;
}
julkinen abstrakti void Näyttö ( int syvyys );
}
/// <summary>
/// Komposiitti - komposiittiobjekti
/// </summary>
/// <li>
/// <lu>määrittää sellaisten komponenttien käyttäytymisen, joilla on lapsia;</lu>
/// < lu >tallentaa lapsikomponentteja;</lu>
/// <lu>toteuttaa alihallintaan ja käyttöliittymään liittyvät toiminnot
/// <see cref="Component"/></lu>
/// </li>
-luokan Yhdistelmä : Komponentti
{
yksityinen luettelo < Komponentti > lapset = uusi Lista < Komponentti >();
// Rakentaja
public Composite ( merkkijonon nimi ) : base ( nimi )
{
}
public void Lisää ( komponenttikomponentti ) { lapset . _ Lisää ( komponentti ); }
public void Poista ( komponenttikomponentti ) { lapset . _ Poista ( komponentti ); }
julkinen ohitus void Näyttö ( syvyys ) { Konsoli . _ WriteLine ( uusi merkkijono ( '-' , syvyys ) + nimi );
// Näytä lapsisolmut rekursiivisesti foreach ( komponenttikomponentti lapsissa ) { komponentti . Näyttö ( syvyys + 2 ); } } }
/// <summary>
/// Lehti - lehti
/// </summary>
/// <remarks>
/// <li>
/// <lu>esittää koostumuksen lehtisolmua, eikä sillä ole lapsia;< /lu>
/// <lu>määrittää primitiivisten objektien käyttäytymisen koostumuksessa;</lu>
/// </li>
/// </remarks>
class Leaf : Komponentti
{
// Rakentajan
julkinen lehti ( merkkijonon nimi ) : kanta ( nimi )
{
}
julkinen ohitus void Näyttö ( syvyys ) { Konsoli . _ WriteLine ( uusi merkkijono ( '-' , syvyys ) + nimi ); } }
C++ esimerkki
Lähdeteksti C++:ssa
#include <iostream>
#include <list>
#include <algoritmi>
#sisällytä <muisti>
class IText {
julkinen :
typedef std :: jaettu_ptr < IText > SPtr ;
virtuaalinen tyhjiöpiirto ( ) = 0 ;
virtual void add ( const SPtr & ) {
throw std :: runtime_error ( "IText: Ei voi lisätä lehteen" );
}
virtuaalinen void poista ( const SPtr & ){
throw std :: runtime_error ( "IText: Ei voida poistaa lehdestä" );
}
};
class CompositeText : public IText {
julkinen :
void add ( const SPtr & sptr ){
lapset_ . push_back ( sptr );
}
void remove ( const SPtr & sptr ){
lapset_ . poista ( sptr );
}
void korvata ( const SPtr & oldValue , const SPtr & newValue ){
std :: korvaa ( lapset_ . alkaa () , lapset_ . loppu (), oldValue , newArvo );
}
virtuaalinen void piirto (){
for ( SPtr & sptr : children_ ){
sptr -> piirrä ();
}
}
yksityinen :
std :: lista < SPtr > lapset_ ;
};
class Letter : public IText {
julkinen :
Kirjain ( merkki c ) : c_ ( c ) {}
virtuaalinen void piirto (){
std :: cout << c_ ;
}
yksityinen :
char c_ ;
};
int main (){
CompositeText lause ;
IText :: SPtr lSpace ( uusi kirjain ( ' ));
IText :: SPtr lExcl ( uusi kirjain ( '!' ));
IText :: SPtr lPilkku ( uusi kirjain ( ',' ));
IText :: SPtr lNewLine ( uusi kirjain ( '\n' ));
IText :: SPtr lH ( uusi kirjain ( 'H' )); // kirjain 'H' IText :: SPtr le ( uusi kirjain ( 'e' )); // kirjain 'e' IText :: SPtr ll ( uusi kirjain ( 'l' )); // kirjain 'l' IText :: SPtr lo ( uusi kirjain ( 'o' )); // kirjain 'o' IText :: SPtr lW ( uusi kirjain ( 'W' )); // kirjain 'W' IText :: SPtr lr ( uusi kirjain ( 'r' )); // kirjain 'r' IText :: SPtr ld ( uusi kirjain ( 'd' )); // kirjain 'd' IText :: SPtr li ( uusi kirjain ( 'i' )); // kirjain 'i'
IText :: SPtr wHello ( uusi komposiittiteksti );
hei -> lisää ( lH );
hei -> lisää ( le );
hei -> lisää ( ll );
hei -> lisää ( ll );
hei -> lisää ( lo );
IText :: SPtr wWorld ( uusi CompositeText ); // sana "Maailma" wWorld -> add ( lW );
wWorld -> add ( lo );
wWorld -> add ( lr );
wWorld -> lisää ( ll );
wWorld -> lisää ( ld );
lause . lisää ( hei );
lause . lisää ( lComma );
lause . lisää ( lSpace );
lause . lisää ( world );
lause . lisää ( lExcl );
lause . lisää ( lNewLine );
lause . piirtää (); // tulostaa "Hei, maailma!\n"
IText :: SPtr wHi ( uusi komposiittiteksti ); // sana "Hei" wHi -> add ( lH );
whi -> lisää ( li );
lause . korvaa ( hei , whi );
lause . piirtää (); // tulostaa "Hei, maailma!\n"
lause . poista ( wWorld );
lause . poista ( lSpace );
lause . poista ( lComma );
lause . piirtää (); // tulostaa "Hei!\n"
paluu 0 ;
}
Esimerkki D:ssä
Lähdeteksti D-kielellä
tuonti std . stdio ;
abstrakti luokka TInfo
{
suojattu :
merkkijonon nimi ;
julkinen :
void Info ();
}
luokka TFile : TInfo
{
suojattu :
uint - koko ;
public :
this ( const string theName , uint theSize )
{
nimi = nimi ;
koko = koko ;
}
void Info ()
{
writefln ( "%s\t%d" , nimi , koko );
}
}
luokka TDir : TInfo
{
suojattu :
TInfo [ ] info ;
public :
this ( const string theName )
{
nimi = nimi ;
}
void Info ()
{
writefln ( "[%s]" , nimi );
foreach ( f ; info )
{
f . info ();
}
}
void Lisää ( TInfo theInfo )
{
info ~= theInfo ;
}
}
void main ()
{
TDir ensimmäinen = new TDir ( "ensimmäinen" );
ensin . Lisää ( new TFie ( "a.txt" , 100 ));
ensin . Lisää ( uusi TFile ( "b.txt" , 200 ));
ensin . Lisää ( new TFie ( "c.txt" , 300 ));
TDir toinen = uusi TDir ( "toinen" );
toinen . Lisää ( uusi TFile ( "d.txt" , 400 ));
toinen . Lisää ( new TFie ( "e.txt" , 500 ));
TDir juuri = uusi TDir ( "juuri" );
juuri . Lisää ( ensimmäinen );
juuri . Lisää ( toinen );
juuri . info ();
}
Python-esimerkki
Lähdekoodi Pythonissa
abc importista ABCMeta , abstrakti menetelmä
luokan yksikkö ( metaclass = ABCMeta ):
"""
Abstrakti komponentti, tässä tapauksessa se on yksikkö (yksikkö voi
koostua yhdestä tai useammasta sotilasta)
"""
@abstractmethod
def print ( self ) -> Ei mitään :
"""
Tulostuskomponentin tiedot
"""
hyväksytään
luokan jousimies ( yksikkö ):
"""
Jousimies
"""
def print ( itse ) -> Ei mitään :
tulosta ( 'archer' , end = '' )
luokan ritari ( Yksikkö ):
"""
Ritari
"""
def print ( itse ) -> Ei mitään :
tulosta ( 'knight' , end = ' ' )
luokan Miekkasoturi ( Yksikkö ):
"""
Miekkasoturi
"""
def print ( itse ) -> Ei mitään :
tulosta ( 'swordsman' , end = ' ' )
luokan joukkue ( Yksikkö ):
"""
Linkkijä on useamman henkilön ryhmä. Voi sisältää myös
muita linkkiryhmiä.
"""
def __init__ ( itse ):
itse . _yksikköä = []
def print ( self ) -> None :
print ( "Squad {} (" . format ( self . __hash__ ()), end = ' ' )
for u in self . _units :
u . print ()
print ( ')' )
def add ( itse , yksikkö : Yksikkö ) -> Ei mitään :
"""
Uuden yksikön lisääminen
:param yksikkö: yksikkö (voi olla joko perusta tai rakentaja) """ itse . _yksikköä . liittää ( yksikkö ) yksikkö . print () print ( 'joined squad {} ' . muoto ( itse . __hash__ ())) tulosta ()
def remove ( itse , yksikkö : Yksikkö ) -> Ei mitään :
"""
Poista yksikkö nykyisestä rakentajasta
:param yksikkö: yksikköobjekti """ for u in self . _yksiköt : jos u == yksikkö : itse . _yksikköä . poista ( u ) u . print () print ( 'vasen yksikkö {} ' . muoto ( itse . __hash__ ())) print () break else : unit . print () print ( 'ei löydy ryhmästä {} ' . muoto ( itse . __hash__ ())) print ()
if __name__ == '__main__' :
print ( 'OUTPUT:' )
squad = Squad ()
squad . lisää ( Knight ())
joukkue . lisää ( Knight ())
joukkue . lisää ( Jousimies ())
miekkasoturi = Swordsman ()
squad . lisätä ( miekkamies )
joukkue . poista ( miekkamies )
-ryhmä . print ()
squad_big = Ryhmä () squad_big . lisää ( Miekkasoturi ()) squad_big . lisää ( Miekkasoturi ()) squad_big . lisätä ( squad ) squad_big . tulosta ()
''' TULOS
:
Knight on liittynyt -9223363262492103834
ritari liittyi ryhmään -9223363262492103834
jousiampuja liittyi ryhmään -9223363262492103834
miekkamies liittyi joukkueeseen -9223363262492103834
miekkamies lähti ryhmästä -9223363262492103834
Ryhmä -9223363262492103834 (ritarijousimies)
miekkamies liittyi ryhmään 8774362671992
miekkamies liittyi joukkueeseen 8774362671992
Ryhmä -9223363262492103834 (ritarijousimies)
liittyi ryhmään 8774362671992
Squad 8774362671992 ( miekkamies miekkamies Squad -9223363262492103834 ( ritari jousimies )
'
''
PHP5 esimerkki
PHP5 lähdekoodi
<?php
abstrakti luokka Komponentti
{
suojattu $nimi ;
julkinen funktio __konstrukti ( $nimi )
{
$this -> name = $nimi ;
}
julkinen abstrakti toimintonäyttö ( );
}
class Komposiitti laajenee Komponentti
{
yksityinen $lapset = array ();
julkinen funktio add ( Komponentti $komponentti )
{
$this -> children [ $komponentti -> nimi ] = $komponentti ;
}
public function poista ( Komponentti $komponentti )
{
unset ( $this -> children [ $komponentti -> nimi ]);
}
julkinen toiminto näyttö ()
{
foreach ( $this -> children as $child ) {
$lapsi -> näyttö ();
}
}
}
class Lehti laajenee Komponentti
{
julkinen funktionäyttö () { print_r ( $this - > name ); } }
// Luo puurakenne
$juuri = new Komposiitti ( "juuri" );
$juuri -> add ( new Leaf ( "Leaf A" ));
$juuri -> add ( new Leaf ( "Leaf B" ));
$comp = uusi komposiitti ( "CompositeX" );
$comp -> add ( new Leaf ( "Leaf XA" ));
$comp -> add ( new Leaf ( "Leaf XB" ));
$juuri -> lisää ( $comp );
$juuri -> add ( new Leaf ( "Leaf C" ));
// Lisää ja poista lehti
$leaf = new Leaf ( "Leaf D" );
$juuri -> lisää ( $lehti );
$juuri -> poista ( $lehti );
// Näytä puu rekursiivisesti
$root -> näyttö ();
?>
PHP5 ulkoisen iteraattorin linkityksen esimerkki
PHP5 lähdekoodi
/**
* Säveltäjäkuvio ulkoisella iteraattorilla
* Iteraattori käyttää rekursiota iteroidakseen elementtipuun läpi
*/
namespace compositeIterator {
/**
* Asiakas käyttää AComponent-käyttöliittymää objektien kanssa työskentelyyn.
* AComponent-liitäntä määrittää käyttöliittymän kaikille komponenteille: sekä yhdistelmille että lehtisolmuille.
* AComponent voi toteuttaa oletuskäyttäytymisen add() remove() getChild()- ja muille operaatioille
*/
abstrakti luokka AComponent
{
julkinen $customPropertyName ;
julkinen $customPropertyDescription ;
/**
* @param AComponent $komponentti
*/
public function add ( $komponentti )
{
throw new \Exception ( "Ei tuettu toiminto" );
}
/**
* @param AComponent $komponentti
*/
julkinen toiminto poista ( $komponentti )
{
throw new \Exception ( "Toiminta ei tueta" );
}
/**
* @param int $int
*/
public function getChild ( $int )
{
throw new \Exception ( "Toiminta ei tueta" );
}
/**
* @return IPhpLikeIterator
*/
abstrakti funktio createIterator ();
public function operation1 ()
{
throw new \Exception ( "Ei tuettu toiminto" );
}
}
/**
* Leaf perii add() remove() getChild(-menetelmät, mikä ei välttämättä ole järkevää lehtisolmulle.
* Vaikka lehtisolmua voidaan pitää solmuna, jolla ei ole lapsia
*
* Leaf määrittelee yhdistelmäelementtien toiminnan Tätä varten se toteuttaa Composite interfacen tukemat toiminnot
*/
luokka Leaf extends AComponent
{
julkinen toiminto __konstrukti ( $nimi , $description = '' )
{
$this -> customPropertyName = $nimi ;
$this -> customPropertyDescription = $ kuvaus ;
}
public function createIterator ()
{
return new NullIterator ();
}
public function operation1 ()
{
echo ( " \n Olen lehti { $this -> customPropertyName } , en halua tehdä toimintoa 1. { $this -> customPropertyDescription } " );
}
}
luokka NullIterator toteuttaa IPhpLikeIterator
{
public function valid ()
{
return ( false );
}
public function next ()
{
return ( false );
}
julkinen funktio nykyinen ()
{
return ( null );
}
public function remove ()
{
heittä uusi \CEexception ( 'ei tuettu toiminto' );
}
}
/**
* Komposiittirajapinta määrittää niiden komponenttien toiminnan, joilla on lapsia, ja tarjoaa niille tallennustilan.
*
* Composite toteuttaa myös Leaf-kohtaisia toimintoja. Jotkut niistä eivät voi olla järkeviä yhdistelmille; tällaisissa tapauksissa tehdään poikkeus.
*/
luokka Komposiitti laajentaa AComponent
{
yksityinen $_iterator = null ;
/**
* @var \ArrayObject AComponent[] $komponentit AComponent-tyypin lapsien tallentamiseen
*/
public $komponentit = null ;
public function __construct ( $nimi , $description = '' )
{
$this -> customPropertyName = $nimi ;
$this -> customPropertyDescription = $description ;
}
/**
* @param AComponent $komponentti
*/
julkinen funktio add ( $komponentti )
{
if ( is_null ( $this -> komponentit )) {
$this -> komponentit = new \ArrayObject ;
}
$this -> komponentit -> append ( $komponentti );
}
public function poista ( $komponentti )
{
foreach ( $this -> komponentit kuten $i => $c ) {
if ( $c === $komponentti ) {
unset ( $this -> komponentit [ $i ]);
}
}
}
public function getChild ( $int )
{
return ( $this -> komponentit [ $int ]);
}
public function operation1 ()
{
echo " \n\n $this->customPropertyName $this->customPropertyDescription " ; echo " \n --------------------------------" ;
$iterator = $this -> komponentit -> getIterator ();
while ( $iteraattori -> voimassa ()) {
$komponentti = $iteraattori -> nykyinen ();
$komponentti -> operaatio1 ();
$iteraattori -> seuraava ();
}
}
/**
* @return CompositeIterator
*/
julkinen toiminto createIterator ()
{
if ( on_null ( $this -> _iterator )) {
$this -> _iterator = new CompositeIterator ( $this -> komponentit -> getIterator ());
}
return ( $this -> _iterator );
}
}
/**
* Rekursiivinen komposiittiiteraattori
*/
luokka CompositeIterator toteuttaa IPhpLikeIterator
{
julkinen $pino = array ();
/**
* @param \ArrayIterator $componentsIterator
*/
julkinen funktio __construct ( $componentsIterator )
{
//$this->stack= new \ArrayObject;
$this -> pino [] = $componentsIterator ;
}
public function remove ()
{
heittä uusi \CEexception ( 'ei tuettu toiminto' );
}
public function valid ()
{
if ( tyhjä ( $this -> pino )) {
return ( false );
} else {
/** @var $componentsIterator \ArrayIterator */
// hanki ensimmäinen elementti
$componentsIterator = array_shift ( array_values ( $this -> pino ));
if ( $componentsIterator -> valid ()) {
return ( true );
} else {
array_shift ( $this -> pino );
return ( $this -> valid ());
}
}
}
public function next ()
{
/** @var $componentsIterator \ArrayIterator */
$componentsIterator = nykyinen ( $this -> pino );
$komponentti = $komponentitIterator -> nykyinen ();
if ( $komponentin esiintymä komposiitti ) {
array_push ( $this -> pino , $komponentti -> createIterator ());
}
$componentsIterator -> seuraava ();
//return($komponentti);
}
public function current ()
{
if ( $this -> valid ()) {
/** @var $componentsIterator \ArrayIterator */
// hanki ensimmäinen elementti
$componentsIterator = array_shift ( array_values ( $this -> pino )) ;
return ( $componentsIterator -> nykyinen ());
} else {
return ( null );
}
}
}
/**
* Kaikkien iteraattorien on otettava käyttöön Iterator-liitäntä.
* Tämä käyttöliittymä on osa tavallista php iterator -liitäntää.
* Tietty iteraattori on vastuussa nykyisen iterointipaikan hallinnasta tietyssä kokoelmassa.
*/
käyttöliittymä IPhpLikeIterator
{
/**
* @abstract
* @return boolean on nykyinen elementti
*/
julkinen funktio kelvollinen ();
/**
* @abstract
* @return sekoitettu siirrä kursoria edelleen
*/
julkinen toiminto seuraava ();
/**
* @abstract
* @return sekoitettu saada nykyinen elementti
*/
public function current ();
/**
* poista kokoelman nykyinen elementti
* @abstract
* @return void
*/
julkinen toiminto poista ();
}
class Client
{
/**
* @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 ( $iteraattori -> kelvollinen ()) {
/** @var $komponentti AComponent */
$komponentti = $iteraattori -> nykyinen ();
if ( strstr ( $komponentti -> customPropertyName , 'leaf1' )) {
echo ( " \n Olen asiakas, löysin leaf { $komponentti -> customPropertyName } , jätän sen tähän (ensimmäisenä lehtien teekokoelma). { $komponentti -> customPropertyDescription } " );
}
$iteraattori -> seuraava ();
}
}
}
class Test
{
julkinen staattinen funktio go ()
{
$a = uusi Yhdistelmä ( "c1" );
$b = uusi komposiitti ( "c2" );
$c = uusi komposiitti ( "c3" );
$topItem = uusi komposiitti ( "top item" );
$topItem -> lisää ( $a );
$topItem -> lisää ( $b );
$topItem -> lisää ( $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" ));
$asiakas = uusi asiakas ( $topItem );
$asiakas -> tulostustoiminto1 ();
$client -> printOperation2 ();
}
}
testi :: mene ();
}
PHP5.4 esimerkki
Lähdeteksti PHP5.4:ssä
<?php
käyttöliittymä IComponent {
toimintonäyttö ( );
}
ominaisuus TComponent
{
julkinen $nimi ;
julkinen funktio __konstrukti ( $nimi )
{
$this -> name = $nimi ;
}
julkisen funktion näyttö ()
{
tulosta $this -> name . '<br>' . PHP_EOL ;
}
}
ominaisuus TComposite
{
use TComponent {
TComponent :: display as displaySelf ;
}
suojattu $lapset = array ();
julkinen funktio add ( IComponent $item )
{
$this -> children [ $item -> name ] = $item ;
}
public function poista ( IComponent $item )
{
unset ( $this -> children [ $item -> name ]);
}
julkinen toiminto näyttö ()
{
$this -> displaySelf ();
foreach ( $this -> children as $child ) {
$lapsi -> näyttö ();
}
}
}
luokka Komposiitti toteuttaa IComponent
{
use TComposite ;
}
luokka Leaf toteuttaa IComponent
{
use TComponent ;
}
$juuri = uusi komposiitti ( "juuri" );
$juuri -> add ( new Leaf ( "Leaf A" ));
$juuri -> add ( new Leaf ( "Leaf B" ));
$comp = uusi komposiitti ( "CompositeX" );
$comp -> add ( new Leaf ( "Leaf XA" ));
$comp -> add ( new Leaf ( "Leaf XB" ));
$juuri -> lisää ( $comp );
$juuri -> add ( new Leaf ( "Leaf C" ));
$lehti = uusi lehti ( "Leaf D" );
$juuri -> lisää ( $lehti );
$juuri -> poista ( $lehti );
$juuri -> näyttö ();
Lähdeteksti CoffeeScript-kielellä
Esimerkki yksinkertaisen fysiikan moottorin aihiosta
# Komponenttiluokka
PObject törmää : ( pObj
) -> addChild : (pObj) -> rmChild : (indeksi) -> getChild : (indeksi) ->
#
Lehtiluokka PShape laajentaa PObject törmää : (pObj) -> # ...
# Yhdistelmäluokka
PCollection laajentaa PObject - konstruktoria : -> @children = []
törmää : (pObj) ->
lapsi . törmäys ( pObj ) lapselle paikassa @childs return @ _
addChild : (pObj) ->
@lapset . push ( pObj ) if pObj instanssi PObject
return @
rmChild : (hakemisto) ->
@lapset . liitos ( indeksi , 1 )
paluu @
getChild : (hakemisto) ->
@lapset [ hakemisto ]
Lähdeteksti VB.NET-kielellä
luokan ohjelma
Jaettu SubMain ( )
' Luo puurakenne
Himmeä juuri Komponenttina = Uusi komposiitti ( " juuri" )
juuri . Lisää ( New Leaf ( "Leaf A" ) )
juuri . Lisää ( Uusi lehti ( "Lehti B" ))
Dim comp As Component = Uusi komposiitti ( "Yhdistelmä X" )
comp . Lisää ( Uusi lehti ( "Leaf XA" ) )
comp . Lisää ( Uusi lehti ( "Leaf XB" ) )
juuri . Lisää ( comp )
root . Lisää ( Uusi lehti ( "Leaf C" ))
' Lisää ja poista lehti
Dim leaf As New Leaf ( "Leaf D" )
juuri . Lisää ( lehti )
juuri . Poista ( lehti )
' Näytä puun
juuri rekursiivisesti . Näyttö ( 1 )
Odota käyttäjäkonsolia . lue ()
Lopeta Sub
End Class
'''' <summary>
'''' Komponentti -
''' </summary>
''' <li>
''' <lu>ilmoittaa rajapinnan koostettaville objekteille;</lu>
''' <lu>tarjoaa sopivan toteutuksen oletustoiminnot,
'''' yhteinen kaikille luokille;</lu>
''' <lu>ilmoittaa käyttöliittymän lapsiin pääsyä ja manipulointia varten;</lu>
''' <lu>määrittää käyttöliittymän komponentin ylätason käyttämiseen rekursiivisen rakenteen
''' ja valinnaisesti toteuttaa sen. Tämä ominaisuus on valinnainen;</lu>
''' </li
> MustInherit Class Component
Suojattu nimi merkkijonona
' Constructor
Public Sub New ( ByVal nimi As String )
Me . nimi = nimi
End Sub
Julkinen MustOverride Sub Add ( ByVal c Komponenttina ) Julkinen MustOverride Sub Remove ( ByVal c Komponenttina ) Julkinen MustOverride Sub Display ( ByVal syvyys Kokonaislukuna ) Loppuluokka _ _ _ _
'''' <summary>
'''' Komposiitti - yhdistelmäobjekti
''' </summary>
''' <li>
''' <lu>määrittää sellaisten komponenttien käyttäytymisen, joilla on lapsia;</lu>
''' < lu >tallentaa alikomponentteja;</lu> ''' <lu>toteuttaa
luokan <katso cref ="komponentti"/></lu> ''' </li> alatason hallintaan ja käyttöliittymään liittyvät toiminnot '''
Peri komponentin yksityiset lapset uutena taulukkoluettelona ( )
Constructor
Public Sub Uusi ( ByVal nimi As String )
MyBase . Uusi ( nimi )
End Sub
Julkinen ohittaa Sub Add ( ByVal - komponentti komponenttina ) lapsia . Lisää ( komponentti ) End Sub
Julkinen ohittaa Sub Remove ( ByVal - komponentti komponenttina ) lapsia . Poista ( komponentti ) End Sub
Julkinen ohittaa alinäytön ( ByVal - syvyys kokonaislukuna ) - konsoli . WriteLine ( Uusi merkkijono ( "-" c , syvyys ) & nimi )
Näytä alisolmut rekursiivisesti jokaiselle komponentille komponenttina Lapsikomponentissa . _ _ Näyttö ( syvyys + 2 ) Next End Sub End Class
'''' <summary>
'''' Lehti - lehti
''' </summary>
''' <remarks>
''' <li>
''' <lu>edustaa koostumuksen lehtisolmua, eikä sillä ole lapsia;< /lu>
''' <lu>määrittää primitiivisten objektien käyttäytymisen koostumuksessa;</lu>
''' </li>
''' </remarks
> Luokkalehti perii
komponentin
Constructor
Public Sub Uusi ( ByVal nimi As String )
MyBase . Uusi ( nimi )
End Sub
Julkinen ohittaa Sub Add ( ByVal c As Component ) -
konsolin . WriteLine ( "Ei voi lisätä lehteen" )
End Sub
Julkinen ohittaa Sub Remove ( ByVal c As Component ) -
konsolin . WriteLine ( "Ei voida poistaa lehdestä" )
End Sub
Julkinen ohittaa alinäytön ( ByVal - syvyys kokonaislukuna ) - konsoli . WriteLine ( Uusi merkkijono ( "-"c , syvyys ) & nimi ) End Sub End Class
Delphi esimerkki
Lähdeteksti Delphissä
ohjelma CompositePattern ;
{$APPTYPE CONSOLE}
käyttää
SysUtils , Contnrs ;
tyyppi
TCustomLetter = luokka
julkinen
menettely Draw ; virtuaalinen ; abstrakti ;
loppu ;
tyyppi
TLetter = luokka ( TCustomLetter )
yksityinen
FLetter : Char ;
julkinen
konstruktori Luo ( aLetter : Char ) ;
menettely Piirrä ; ohittaa ;
loppu ;
rakentaja TLetter . Luo ( aLetter : Char ) ;
alkaa
FLetter := aLetter ;
loppu ;
menettelyTletter . _ piirtää ; alkaa Kirjoita ( FLetter ) ; loppu ;
tyyppi
TWord = luokka ( TCustomLetter )
yksityinen
FWord : String ;
julkinen
konstruktori Luo ( aWord : String ) ;
menettely Piirrä ; ohittaa ;
loppu ;
rakentaja TWord . Luo ( aWord : String ) ;
begin
FWord := aWord ;
loppu ;
menettely TWord . piirtää ;
alkaa
Kirjoita ( FWord ) ;
loppu ;
tyyppi
TText = luokka ( TCustomLetter )
yksityinen
FList : TObjectList ;
julkinen
rakentaja Luo ;
tuhoaja Tuhoa ; ohittaa ;
menettely Lisää ( aCustomLetter : TCustomLetter ) ;
menettely Piirrä ; ohittaa ;
loppu ;
rakentaja TText . luoda ;
alkaa
perinnöllinen ;
FList := TObjectList . luoda ;
loppu ;
destructor TText . Tuhoa ;
aloita
FList . Ilmainen ;
perinnöllinen ;
loppu ;
menettely TTeksti . Lisää ( aCustomLetter : TCustomLetter ) ;
aloita
FList . Lisää ( aCustomLetter ) ;
loppu ;
menettely TTeksti . piirtää ;
var
vI : Kokonaisluku ;
aloita
vI := 0 - Pred ( FList . Count ) do TLetter ( FList [ vI ] ) . piirtää ; loppu ;
var
vRootText , vSubText : TText ;
begin
vRootText := TText . luoda ;
vSubText := TTeksti . luoda ;
kokeile
vSubTextiä . Lisää ( TLetter . Luo ( '!' )) ;
vSubText . Lisää ( TLetter . Luo ( '!' )) ;
vSubText . Lisää ( TLetter . Luo ( '!' )) ;
vSubText . Lisää ( TWord . Luo ( ' =)' )) ;
vRootText . Lisää ( TLetter.Create ( ' H' ) ) ; vRootText . Lisää ( TLetter.Create ( ' E ' )) ; vRootText . Lisää ( TLetter.Create ( ' L' ) ) ; vRootText . Lisää ( TLetter.Create ( ' L' ) ) ; vRootText . Lisää ( TLetter.Create ( ' O' ) ) ; vRootText . Lisää ( TLetter . Luo ( ' )) ; vRootText . Lisää ( TWord . Luo ( 'Maailma' )) ; vRootText . Lisää ( vSubText ) ;
vRootText . piirtää ;
lopuksi
vRootText . Tuhoa ;
loppu ;
Readln ;
loppua .
JavaScript lähdekoodi
function Komponentti () {
tämä . nimi = '' ;
tämä . arvo = 0 ;
tämä . suorita = funktio () { };
}
function Leaf ( nimi , arvo ) {
this . nimi = nimi ;
tämä . arvo = arvo ;
tämä . suorita = function () {
return this . arvo ;
};
}
lehtiä . prototyyppi = Objekti . luoda ( Komponentti . prototyyppi );
lehtiä . prototyyppi . rakentaja = Leaf ;
function Yhdistelmä ( nimi ) {
var self = this ;
var lapset = [];
tämä . nimi = nimi ;
tämä . add = funktio ( komponentti ) {
lapset . push ( komponentti );
};
tämä . poista = funktio ( komponentinnimi ) {
var newChildren = [];
lapset . forEach ( funktio ( komponentti ) {
if ( komponentin . nimi !== komponentinnimi ) {
newChildren . push ( komponentti );
}
});
lapset = uudetLapset ;
};
tämä . suorita = function () {
lapset . forEach ( funktio ( komponentti ) {
itse . arvo = ( itse . arvo || 0 ) + komponentti . suorita ();
});
palauta itsesi . arvo ;
};
}
Komposiitti . prototyyppi = Objekti . luoda ( Komponentti . prototyyppi );
Komposiitti . prototyyppi . konstruktori = Komposiitti ;
// Sovellus
var kitchen = new Composite ( 'Kitchen' );
keittiö . add ( new Leaf ( 'Yläosio' , 5200 ) );
keittiö . add ( new Leaf ( 'Top Double Section' , 10000 ) );
keittiö . add ( new Leaf ( 'Alempi osa' , 4500 ) );
keittiö . add ( new Leaf ( 'Alakulmaosa' , 7800 ) );
var equipment = new Composite ( 'Equipment' );
varusteet . add ( new Leaf ( 'Kaasuliesi' , 26400 ) );
varusteet . add ( new Leaf ( 'Jääkaappi' , 32300 ) );
varusteet . add ( new Leaf ( 'Astianpesukone' , 21600 ) );
keittiö . lisätä ( varusteet );
konsoli . loki ( 'Yhteensä: ' + keittiö . suorita () + ' RUB' );
Nopea esimerkki
Nopea lähdekoodi
protokolla Item {
var id : UInt32 { get }
var name : String { get }
func desctiption () -> merkkijono
}
class Button : Item {
var id : UInt32 = arc4random ()
var name : String = "Button"
func desctiption () -> String {
return "ID: \( id ) | \( nimi ) "
}
}
luokka Tunniste : Item {
var id : UInt32 = arc4random ()
var name : String = "Label"
func desctiption () -> String {
return "ID: \( id ) | \( nimi ) "
}
}
luokkanäkymä : Item { _
var komponentit : [ Item ] = []
var id : UInt32 = arc4random ()
var name : String = "Näytä"
func desctiption () - > String {
paluukomponentit . vähennä ( "" , { " \( $0 ) \( $1 . desctiption ()) " }) }
func add ( item : Item ) {
komponentit . liittää ( kohde )
}
func remove ( item : Item ) {
if let index = komponentit . firstIndex ( missä : { $0 . id == item . id }) {
komponentit . poista ( osoitteessa : hakemisto )
}
}
}
// Käytä komposiittia
anna painike = Button ()
tulosta ( button.desctiption ( ) )
anna katsella = Näytä ()
näkymä . lisää ( kohde : Painike ())
näkymä . lisää ( tuote : Label ())
tulosta ( view.desctiption ( ) )
Linkit