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 .
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 :: gå ();
}
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 ();
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 ]
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-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