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 .
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 ();
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 ]
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 .
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