Dekoratør (designmønster)

Den aktuelle version af siden er endnu ikke blevet gennemgået af erfarne bidragydere og kan afvige væsentligt fra den version , der blev gennemgået den 19. september 2018; checks kræver 19 redigeringer .
Dekoratør
dekoratør
Type strukturel
Formål for dynamisk forbindelse til objektet for yderligere forpligtelser
fordele
  • der er ikke behov for at oprette underklasser for at udvide objektets funktionalitet;
  • evnen til dynamisk at inkludere ny funktionalitet før eller efter objektets hovedfunktionalitet ConcreteComponent.
Relaterede skabeloner Facade , Adapter
Beskrevet i Design Patterns Ja

En  dekoratør er et strukturelt designmønster designet til dynamisk at forbinde yderligere adfærd til et objekt . Decorator-mønsteret giver et fleksibelt alternativ til praksis med underklassificering for at udvide funktionaliteten.

Nøglefunktioner

Udfordring

Objektet, der formodes at blive brugt, udfører hovedfunktionerne. Det kan dog være nødvendigt at tilføje noget ekstra funktionalitet til det, der kører før, efter eller endda i stedet for objektets hovedfunktionalitet.

Løsning

Dekoratøren sørger for at udvide funktionaliteten af ​​et objekt uden at definere underklasser.

Medlemmer

En klasse ConcreteComponent er en klasse, hvortil der tilføjes ny funktionalitet ved hjælp af Decorator-mønsteret. I nogle tilfælde leveres den underliggende funktionalitet af klasser, der stammer fra ConcreteComponent. I sådanne tilfælde er klassen ConcreteComponentikke længere konkret, men abstrakt . En abstrakt klasse Componentdefinerer en grænseflade til brug af alle disse klasser.

Konsekvenser

  1. Den ekstra funktionalitet er implementeret i små objekter. Fordelen er muligheden for dynamisk at tilføje denne funktionalitet før eller efter hovedfunktionaliteten i ConcreteComponent.
  2. Giver dig mulighed for at undgå overbelastning med funktionelle klasser på de øverste niveauer af hierarkiet
  3. Dekorator og dens komponenter er ikke identiske

Implementering

Der oprettes en abstrakt klasse, der repræsenterer både den oprindelige klasse og de nye funktioner, der er tilføjet klassen. I dekoratørklasser kaldes nye funktioner i den ønskede rækkefølge, enten før eller efter det næste objekt kaldes.

Hvis det ønskes, er det fortsat muligt at bruge den oprindelige klasse (uden at udvide funktionaliteten), hvis en reference til dens objekt er bevaret.

Noter og kommentarer

Anvendelse af en skabelon

Filterdrivere i Windows -kernen ( WDM (Windows Driver Model) -arkitektur ) er dekoratorer. På trods af det faktum, at WDM er implementeret i et ikke-objekt C -sprog , viser det tydeligt designmønstre - en dekoratør, en kæde af ansvarsområder og en kommando ( irp- objekt ).

COM (Component Object Model) -arkitekturen understøtter ikke implementeringsarv, i stedet foreslås det at bruge dekoratorer (i denne arkitektur kaldes dette "aggregation"). Samtidig løser arkitekturen (ved hjælp af pUnkOuter-mekanismen) det objektidentitetsproblem, der opstår ved brug af dekoratører - identiteten af ​​et aggregat er identiteten af ​​dets yderste dekoratør.

Eksempler

Kotlin

Et eksempel i Kotlin fun main () { LoggingNotifier ( FancyNotifier ( ConsoleNotifier () ) ) ). underrette ( "Hej, verden!" ) } interface Notifier { sjov notify ( message : String ) } class ConsoleNotifier : Notifier { override fun notify ( message : String ) { println ( message ) } } class LoggingNotifier ( privat val notifier : Notifier ) : Notifier { override fun notify ( meddelelse : String ) { notifier . underrette ( besked ) println ( " LOG - $ besked " ) // Som en logger } } klasse FancyNotifier ( privat val notifier : Notifier ) : Notifier { override fun notify ( meddelelse : String ) { val border = "-" . gentag ( meddelelseslængde ) underretning . _ _ underrette ( """ $ kant $ besked $ grænse """ . trimIndent ()) } }

Ruby

Eksempel i Ruby modul DecoratorPattern # Udvider grundlæggende funktionalitet ved at kombinere flere Decoratorer klasse Source def initialize ( line ) @line = line end def write_line @line end end # Abstrakt Decorator modul Decorator def initialize ( source ) @source = source end def write_line raise NotImplementedError end end # Betondekorator klasse Upcaser inkluderer Decorator def write_line @kilde . skrive_linje . upcase ende ende # Betondekoratørklasse Tidsstempel inkluderer dekoratør def write_line " #{ Time . now . strftime ( '%H:%m' ) } #{ @source . write_line } " end end # Betondekoratør klasse Datostempler inkluderer dekoratør def write_line " #{ Time . now . strftime ( '%d.%m.%y' ) } #{ @source . write_line } " end end def selv . køre sætter '=> Dekoratør' kilde = kilde . ny ( 'Lorem ipsum dolor sit amet' ) sætter "Kilde: \n => #{ source . write_line } " upcased = Upcaser . new ( source ) sætter "Upcased: \n => #{ upcased . write_line } " tidsstemplet = tidsstempel . new ( source ) sætter "Timesamped: \n => #{ timestamped . write_line } " datestamped = datostempel . new ( source ) sætter "Datestamped: \n => #{ datestamped . write_line } " upcased_timestamped = Tidsstempel . new ( Upcaser . new ( source )) sætter "Upcased and timestamped: \n => #{ upcased_timestamped . write_line } " upcased_datestamped_timestamped = Datostemplet . new ( Tidsstempler . ny ( Upcaser . ny ( kilde ))) sætter "Upcased, datestamped and timestamped: \n => #{ upcased_datestamped_timestamped . write_line } " datestamped_timestamped = Datestamped . new ( Timesamped . new ( source )) sætter "Datestamped and timestamped: \n => #{ datestamped_timestamped . write_line } " sætter ' ' ende Dekoratørmønster . løb # => Dekoratør # Kilde: # => Lorem ipsum dolor sit amet # Upcased: # => LOREM IPSUM DOLOR SIT AMET # Tidsstemplet: # => 18:03 Lorem ipsum dolor sit amet # Datostemplet: # => 03/29/ 19 Lorem ipsum dolor sit amet # Upcased og tidsstemplet: # => 18:03 LOREM IPSUM DOLOR SIT AMET # Upcased, datostemplet og tidsstemplet: # => 03/29/19 18:03 LOREM IPSUM DOLOR SIT AMET # Datestamped: # => 03/29 .19 18:03 Lorem ipsum dolor sit amet

Java

Java eksempel offentlig grænseflade InterfaceComponent { void doOperation (); } klasse MainComponent implementerer InterfaceComponent { @Override public void doOperation () { System . ud . print ( "Verden!" ); } } abstrakt klasse Decorator implementerer InterfaceComponent { beskyttet InterfaceComponent- komponent ; public Decorator ( InterfaceComponent c ) { component = c ; } @Override public void doOperation () { component . doOperation (); } public void newOperation () { System . ud . println ( "Gør ingenting" ); } } klasse DecoratorSpace udvider Decorator { public DecoratorSpace ( InterfaceComponent c ) { super ( c ); } @Override public void doOperation () { System . ud . print ( "" ); super . doOperation (); } @Override public void newOperation () { System . ud . println ( "Ny rumoperation" ); } } klasse DecoratorComma udvider Decorator { public DecoratorComma ( InterfaceComponent c ) { super ( c ); } @Override public void doOperation () { System . ud . print ( "," ); super . doOperation (); } @Override public void newOperation () { System . ud . println ( "Ny kommaoperation" ); } } klasse DecoratorHello udvider Decorator { public DecoratorHello ( InterfaceComponent c ) { super ( c ); } @Override public void doOperation () { System . ud . print ( "Hej" ); super . doOperation (); } @Override public void newOperation () { System . ud . println ( "Ny hej operation" ); } } klasse Main { public static void main ( String ... s ) { Decorator c = new DecoratorHello ( new DecoratorComma ( new DecoratorSpace ( new MainComponent ()))); c . doOperation (); // Resultatet af programmet "Hej, verden!" c . nyoperation (); // Ny hej operation } }

C#

Eksempel i C# bruger System ; namespace Decorator { class MainApp { static void Main () { // Create ConcreteComponent and two Decorators ConcreteComponent c = new ConcreteComponent (); ConcreteDecoratorA dA = ny ConcreteDecoratorA (); ConcreteDecoratorB dB = new ConcreteDecoratorB (); // Link dekoratører dA . SetComponent ( c ); dB . SetComponent ( dA ); d.A. _ operationer (); Konsol . skriveLine (); dB . operationer (); // Vent på brugerkonsollen . læs (); } } /// <resumé> /// Komponent - komponent /// </summary> /// <remarks> /// <li> /// <lu>definer en grænseflade for objekter, der kan være dynamisk /// yderligere ansvar tildelt;</lu> /// </li> /// </remarks> abstrakt klasse Komponent { public abstract void Operation (); } /// <resumé> /// ConcreteComponent - konkret komponent /// </summary> /// <remarks> /// <li> /// <lu>definerer et objekt, der har yderligere ansvar</lu> / // </li> /// </remarks> class ConcreteComponent : Component { public override void Operation () { Console . skriv ( "hej" ); } } /// <resumé> /// Decorator - decorator /// </summary> /// <remarks> /// <li> /// <lu>gemmer en reference til et objekt <see cref="Component" /> og definerer en grænseflade /// svarende til grænseflade <see cref="Component"/></lu> /// </li> /// </remarks> abstract class Decorator : Component { protected Component component ; public void SetComponent ( Component component ) { this . komponent = komponent ; } public override void Operation () { if ( component != null ) { component . operationer (); } } } /// <resumé> /// ConcreteDecoratorA - betondekoratør /// </summary> /// <remarks> /// <li> /// <lu>Udfører hovedopgaven</lu> /// < / li> /// </remarks> class ConcreteDecoratorA : Decorator { public override void Operation () { base . operationer (); } } /// <resumé> /// ConcreteDecorator - betondekoratør /// </summary> /// <remarks> /// <li> /// <lu>Udfører hovedopgaven + yderligere</lu> // / </li> /// </remarks> class ConcreteDecoratorB : Decorator { public override void Operation () { base . operationer (); Konsol . Skriv ( "Fred!" ); } } }

C++

Eksempel i C++ #include <iostream> #inkluder <hukommelse> klasse IComponent { offentligt : virtuel void operation () = 0 ; virtuel ~ IComponent (){} }; klasse Komponent : offentlig IComponent { offentligt : virtuel void operation () { std :: cout << "Verden!" << std :: endl ; } }; klasse DecoratorOne : offentlig IComponent { std :: shared_ptr < IComponent > m_component ; offentligt : DecoratorOne ( std :: shared_ptr < IComponent > komponent ) : m_component ( komponent ) {} virtuel void operation () { std :: cout << ", " ; m_component -> operation (); } }; klasse DecoratorTwo : offentlig IComponent { std :: shared_ptr < IComponent > m_component ; offentligt : DecoratorTwo ( std :: shared_ptr < IComponent > komponent ) : m_komponent ( komponent ) {} virtuel void operation () { std :: cout << "Hej" ; m_component -> operation (); } }; int main () { DecoratorTwo obj ( std :: make_shared < DecoratorOne > ( std :: make_shared < Komponent > ())); obj . operation (); // udskriver "Hej, verden!\n" return 0 ; }

D

Eksempel på D-sprog import std . stdio ; abstrakt klasse Figur { beskyttet strengnavn ; _ streng getInfo (); } klasse Tom : Figur { overskriv streng getInfo () { return null ; } } klasse Cirkel : Figur { beskyttet Figur figur ; this ( figur f ) { figur = f ; navn = "cirkel" ; } tilsidesæt streng getInfo () { returner navn ~ figur . getInfo (); } } klasse Bar : Figur { beskyttet Figur figur ; this ( figur f ) { figur = f ; navn = "bar" ; } tilsidesætte streng getInfo () { return figure . getInfo () ~ navn ; } } void main () { Figurfigurer = new Bar ( new Circle ( new Circle ( new Circle ( new Empty ( ))))); writeln ( figurer.getInfo ( ) ); }

Python

Nedenfor er et eksempel på implementering af designmønsteret. Der er funktions- og klassedekoratører i Python , som har et andet koncept end designmønsteret.

Python eksempel [1] """ Demonstrerede dekoratører i en verden med et 10x10 gitter af værdier ​​0-255. """ import tilfældig def s32_to_u16 ( x ): hvis x < 0 : tegn = 0xf000 ellers : tegn = 0 bund = x & 0x00007fff retur bund | skilt def seed_from_xy ( x , y ): returner s32_to_u16 ( x ) | ( s32_to_u16 ( y ) << 16 ) klasse RandomSquare : def __init__ ( s , seed_modifier ): s . seed_modifier = frø_modifier def get ( s , x , y ): frø = frø_fra_xy ( x , y ) ^ s . seed_modifier tilfældig . frø ( frø ) returnerer tilfældigt . randint ( 0 , 255 ) klasse DataSquare : def __init__ ( s , initial_value = Ingen ): s . data = [ initial_value ] * 10 * 10 def get ( s , x , y ): returner s . data [ ( y * 10 ) + x ] # ja: disse er alle 10x10 def set ( s , x , y , u ): s . data [ ( y * 10 ) + x ] = u klasse CacheDecorator : def __init__ ( s , dekoreret ): s . dekoreret = dekoreret s . cache = DataSquare () def get ( s , x , y ): hvis s . cache . ( x , y ) == Ingen : s . cache . sæt ( x , y , s . dekoreret . ( x , y ) ) retur s . cache . ( x , y ) klasse MaxDecorator : def __init__ ( s , dekoreret , max ): s . dekoreret = dekoreret s . max = max def get ( s , x , y ): hvis s . dekoreret . ( x , y ) > s . max : afkast s . max afkast s . dekoreret . ( x , y ) klasse MinDecorator : def __init__ ( s , dekoreret , min ): s . dekoreret = dekoreret s . min = min def get ( s , x , y ): hvis s . dekoreret . ( x , y ) < s . min : retur s . min retur s . dekoreret . ( x , y ) klasse VisibilityDecorator : def __init__ ( s , dekoreret ): s . dekoreret = dekoreret def ( s , x , y ): returnere s . dekoreret . ( x , y ) def draw ( s ): for y i området ( 10 ): for x i området ( 10 ): udskriv " %3d " % s . ( x , y ), print # Opbyg nu en pipeline af dekoratører: random_square = RandomSquare ( 635 ) random_cache = CacheDecorator ( random_square ) max_filtered = MaxDecorator ( random_cache , 200 ) min_filtered = MinDecorator ( max_filtred , 100 ) final = VisibilityDecorator ( min_filtered ) endelig . tegne ()

Output (bemærk brugen af ​​en pseudo-tilfældig talgenerator):

100 100 100 100 181 161 125 100 200 200 100 100 200 200 200 200 200 200 184 162 100 155 200 200 200 200 200 143 100 200 144 2001 143 114 200 166 136 100 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144 161 100 200 200 200 190 125 100 177 150 200 100 175 111 195 195 128 100 100 100 200 200 200 200 129 105 112 100 101 200 200 100 100 100 101 120 180 200 100 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001

PHP

PHP eksempel abstrakt klasse AbstractComponent { abstrakt offentlig funktion operation (); } klasse ConcreteComponent udvider AbstractComponent { public function operation () { // ... } } abstrakt klasse AbstractDecorator udvider AbstractComponent { protected $component ; offentlig funktion __construct ( AbstractComponent $component ) { $this -> component = $component ; } } class ConcreteDecorator udvider AbstractDecorator { public function operation () { // ... udvidet funktionalitet ... $this -> component -> operation (); // ... udvidet funktionalitet ... } } $decoratedComponent = new ConcreteDecorator ( ny ConcreteComponent () ); $decoratedComponent -> operation ();

PHP 5

PHP5 eksempel mest almindeligt brugt <?php interface IText { public function show (); } klasse TextHello implementerer IText { protected $object ; offentlig funktion __construct ( IText $tekst ) { $this -> objekt = $tekst ; } public function show () { echo 'Hej' ; $dette -> objekt -> vis (); } } class TextWorld implementerer IText { protected $object ; offentlig funktion __construct ( IText $tekst ) { $this -> objekt = $tekst ; } public function show () { echo 'verden' ; $dette -> objekt -> vis (); } } class TextSpace implementerer IText { protected $object ; offentlig funktion __construct ( IText $tekst ) { $this -> objekt = $tekst ; } public function show () { echo ' ' ; $dette -> objekt -> vis (); } } klasse TextEmpty implementerer IText { public function show () { } } $decorator = new TextHello ( ny TextSpace ( ny TextWorld ( ny TextEmpty ()))); $decorator -> vis (); // Hello world echo '<br />' . PHP_EOL ; $decorator = new TextWorld ( ny TextSpace ( ny TextHello ( ny TextEmpty ()))); $decorator -> vis (); // Hej Verden

CoffeeScript

Eksempel i CoffeeScript # Komponentklasse Notebook # Markedsføringspris : 500 # $ # Specifikationer hdd : 320 # GB ram : 4 # GB kerne : 'i5 2.3' # GHz # Dekoratørklasse NovaNotebook - konstruktør: (produkt) -> @pris = produkt . pris * 1,3 # Dekoratørklasse ImportNotebook - konstruktør: (produkt) -> @pris = produkt . pris * 1,5 # Dekoratørklasse AppleNotebook - konstruktør: (produkt) -> @pris = produkt . pris * 2,1 macBookInRussia = ny ImportNotebook ny NovaNotebook ny AppleNotebook ny Notebook -konsol . log ( macBookInRussia .price ) _

JavaScript

JavaScript eksempel

Dekoratørmønsteret i dynamisk indtastede sprog kan bruges uden grænseflader og traditionel OOP-arv.

Dette eksempel er kopieret fra den engelske version af artiklen. Beregning af prisen på kaffe:

// ConcreteComponent (klasse til at dekorere senere) funktion Kaffe () { this . pris = funktion () { return 1 ; }; } // Dekorator A funktion Mælk ( kaffe ) { dette . pris = funktion () { returnere kaffe . pris () + 0,5 ; }; } // Dekorator B funktion Pisk ( kaffe ) { dette . pris = funktion () { returnere kaffe . pris () + 0,7 ; }; } // Dekorator C funktion Drys ( kaffe ) { dette . pris = funktion () { returnere kaffe . pris () + 0,2 ; }; } // Kan bruges sådan her: var coffee = new Milk ( new Whip ( new Sprinkles ( new Coffee ()))); advarsel ( kaffe.pris ( ) ) ; // Eller mere visuelt: var kaffe = ny kaffe (); kaffe = nyt Drys ( kaffe ); kaffe = ny Pisk ( kaffe ); kaffe = ny Mælk ( kaffe ); advarsel ( kaffe.pris ( ) );

Implementering af ovenstående C# eksempel. Der er tilføjet en lokal variabel pris til ConcreteComponent , som vil ændre sig både i sig selv og hos dekoratører. Klassenavnene (bortset fra postfixerne "A" og "B") er de samme som navnene på skabelonmedlemmerne.

function Component () { this . operation = funktion () { }; dette . getPrice = funktion () { }; dette . setPrice = funktion () { }; } function ConcreteComponent () { var price = 10 ; dette . operation = funktion () { pris += 4 ; alert ( "Betonkomponent. operation, pris: " + pris ); }; dette . getPrice = function () { return price ; }; dette . sætPris = funktion ( værdi ) { pris = værdi ; }; } ConcreteComponent . prototype = ny komponent (); Betonkomponent . prototype . constructor = ConcreteComponent ; function Decorator () { var komponent ; dette . sætKomponent = funktion ( val ) { komponent = val ; }; dette . getComponent = function () { return komponent ; }; dette . operation = funktion () { komponent . operation (); }; dette . getPrice = funktion () { return komponent . getpris (); }; dette . sætPris = funktion ( værdi ) { komponent . sætpris ( val ); }; } Dekoratør . prototype = ny komponent (); Dekoratør . prototype . konstruktør = Dekoratør ; function ConcreteDecoratorA () { Decorator . ring ( dette ); var operation = dette . drift ; // reference til metoden defineret i Decorator dette . operation = funktion () { dette . setPrice ( denne . getPrice () + 3 ); advarsel ( "ConcreteDecoratorA. operation, pris: " + denne . getPrice ()); operation (); }; } function ConcreteDecoratorB () { var duplicate = this ; // reference til det instansierede objekt (fordi dette kan ændre sig) Decorator . ring ( dette ); var operation = dette . drift ; // reference til metoden defineret i Decorator dette . operation = funktion () { dette . setPrice ( this.getPrice ( ) + 1 ) ; advarsel ( "ConcreteDecoratorB. operation, pris: " + denne . getPrice ()); tilføjet adfærd (); operation (); }; function addedBehavior () { duplicate . setPrice ( duplicate . getPrice () + 2 ); advarsel ( "addedBehavior, price: " + duplicate . getPrice ()); } } // brug c = ny ConcreteComponent (); d1 = new ConcreteDecoratorA (); d2 = new ConcreteDecoratorB (); advarsel ( "original pris: " + c . getPrice ()); // ti d1 . sætKomponent ( c ); d2 . sætKomponent ( d1 ); d2 . operation (); advarsel ( "pris efter konvertering: " + c . getPrice ()); // tyve

VB.NET

Eksempel i VB.NET Navnerumsdekoratør _ klasse program Shared Sub Main () ' Opret ConcreteComponent og to dekoratører Dim C As New ConcreteComponent () Dim D1 As New ConcreteDecoratorA () Dim D2 As New ConcreteDecoratorB () ' Dekoratørreferencer D1 . SetComponent ( C ) D2 . SetComponent ( D1 ) D2 . operation () 'Venter på handling fra brugerkonsollen . Læs () End Sub slutklasse _ ''' <summary> ''' Komponent - komponent ''' </summary> ''' <remarks> ''' <li> ''' <lu>definer en grænseflade for objekter, der dynamisk kan tildeles ''' yderligere ansvar;</lu> ''' </li> ''' </remarks> MustInherit Class Component Public MustOverride Sub Operation () End Class ''' <summary> ''' ConcreteComponent - konkret komponent ''' </summary> ''' <remarks> ''' <li> ''' <lu>definerer et objekt, der har yderligere ansvar</lu> ' '' </li> ''' </remarks> Klasse ConcreteComponent arver komponent Offentlige tilsidesættelser Sub Operation () Konsol . WriteLine ( "ConcreteComponent.Operation()" ) End Sub End Class ''' <summary> ''' Dekoratør - dekoratør ''' </summary> ''' <remarks> ''' <li> ''' <lu> gemmer en reference til et objekt <see cref="Component" /> og definerer en grænseflade ''' svarende til grænseflade <see cref="Component"/></lu> ''' </li> ''' </remarks> MustInherit Class Decorator arver komponent Beskyttet komponent som komponent Public Sub SetComponent ( ByVal component As Component ) Me . komponent = komponent End Sub Offentlige tilsidesættelser Underoperation ( ) Hvis komponent ikke er noget , komponent . Operation () End If End Sub End Class ''' <summary> ''' ConcreteDecorator - betondekoratøren ''' </summary> ''' <remarks> ''' <li> ''' <lu>lægger yderligere ansvar på komponenten.</lu> '' ' </li> ''' </remarks> Klasse ConcreteDecoratorA arver Decorator Private addedState As String Offentlige tilsidesættelser Sub Operation () MyBase . Operation () addedState = "Ny tilstand" -konsol . WriteLine ( "ConcreteDecoratorA.Operation()" ) End Sub End Class ' "BetonDecoratorB" Klasse BetonDecoratorB arver Decorator Offentlige tilsidesættelser Sub Operation () MyBase . Operation () AddedBehavior () Konsol . WriteLine ( "ConcreteDecoratorB.Operation()" ) End Sub Private Sub AddedBehavior () End Sub End Class End Namespace

Delphi

Delphi og Free Pascal støtter klassehjælpere, som gør brugen af ​​dekorationsmønstret unødvendig .

Delphi eksempel program NoMoreDecorators ; type TMyObject = klasse procedure WriteHello ; ende ; TMyObjectHelper = klassehjælper for TMyObject - proceduren WriteHello ( const Navn : string ) ; overbelastning ; ende ; procedure TMyObject . Skriv Hej ; start writeln ( 'Hej' ) ; ende ; procedure TMyObjectHelper . WriteHello ( const Navn : streng ) ; start writeln ( 'Hej, ' , Navn , '!' ) ; ende ; var o : TMyObject ; start o := TMyObject . skabe ; o . Skriv Hej ; o . WriteHello ( 'Jean' ) ; o . Gratis ; ende . Delphi eksempel program DecoratorPattern ; {$APPTYPE KONSOL} bruger SysUtils ; type TInterfaceComponent = klasse offentlig procedure Operation ; virtuel ; abstrakt ; ende ; type TConcreteComponent = klasse ( TInterfaceComponent ) offentlig procedure Operation ; tilsidesætte ; ende ; procedure TConcreteComponent . drift ; begynde Skriv ( 'kan ikke' ) ; ende ; type TDecorator = klasse ( TInterfaceComponent ) privat FComponent : TInterfaceComponent ; offentlig konstruktør Opret ( aComponent : TInterfaceComponent ) ; ende ; konstruktør TDecorator . Opret ( aComponent : TInterfaceComponent ) ; start FComponent := aComponent ; ende ; type TBeforeDecorator = klasse ( TDecorator ) offentlig procedure Drift ; tilsidesætte ; ende ; procedure TBeforeDecorator . drift ; begynde Skriv ( 'Udfør,' ) ; FComponent . drift ; ende ; type TAfterDecorator = klasse ( TDecorator ) offentlig procedure Drift ; tilsidesætte ; ende ; procedure TAefterDecorator . drift ; start FComponent . drift ; Skriv ( 'undskyld' ) ; ende ; type TOverrideDecorator = klasse ( TDecorator ) offentlig procedure Drift ; tilsidesætte ; ende ; procedure TOverrideDecorator . drift ; begynde Skriv ( 'Elsk hinanden!' ) ; ende ; var vSameComponent : TInterfaceComponent ; start vSameComponent := TAfterDecorator . Opret ( TConcreteComponent . Opret ) ; vSameComponent . drift ; // Vil udskrive "kan ikke benåde" Writeln ; vSameComponent := TBeforeDecorator . Opret ( vSameComponent ) ; vSameComponent . drift ; // Vil udskrive "Execute, can't pardon" Writeln ; vSameComponent := TOverrideDecorator . Opret ( vSameComponent ) ; vSameComponent . drift ; // Vil udskrive "Elsk hinanden!" // For nemheds skyld er ødelæggelsen af ​​objekter ikke vist Læsln ; ende .

Swift

Hurtigt eksempel protokol Bog { var title : String { get set } var price : Int { get set } func getPrice () -> Int } klasse BookImpl : Bog { var title : String = "" var pris : Int = 1000 func getPrice () - > Int { returpris } } klasse Rabatbog : Bog { let element : BookImpl var title : String = "Groaming Algorithms" var pris : Int = 0 init ( element : BookImpl ) { self . element = element selv . titel = element . titel selv . pris = element . pris } // 30 % udsalg func getPrice () - > Int { returpris - ( pris * 30 ) / 100 } } // Brug Decorator lad bog = BookImpl () lad rabatBook = Rabatbog ( element : bog ) print ( rabatBook . getPrice ())

Litteratur

  • Alan Shalloway, James R. Trott. Design mønstre. En ny tilgang til objektorienteret design = Designmønstre forklaret: Et nyt perspektiv på objektorienteret design. - M . : "Williams" , 2002. - S. 288. - ISBN 0-201-71594-5 .
  • Eric Freeman, Elizabeth Freeman. Designmønstre = Head First Design Patterns. - Sankt Petersborg. : Peter. — 656 s. - ISBN 978-5-459-00435-9 .

Noter

  1. Dekoratørmønster . wiki.python.org . Hentet 24. oktober 2021. Arkiveret fra originalen 24. oktober 2021.

Links