Decorator (model de design)

Versiunea actuală a paginii nu a fost încă revizuită de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită pe 19 septembrie 2018; verificările necesită 19 modificări .
Decorator
decorator
Tip de structural
Scop pentru racordarea dinamică la obiectul obligaţiilor suplimentare
pro
  • nu este nevoie de a crea subclase pentru a extinde funcționalitatea obiectului;
  • capacitatea de a include dinamic noi funcționalități înainte sau după funcționalitatea principală a obiectului ConcreteComponent.
Șabloane înrudite Fațadă , adaptor
Descris în Design Patterns da

Un  decorator este un model de design structural conceput pentru a conecta dinamic un comportament suplimentar la un obiect . Modelul Decorator oferă o alternativă flexibilă la practica subclasării pentru a extinde funcționalitatea.

Caracteristici cheie

Provocare

Obiectul care se presupune a fi utilizat îndeplinește principalele funcții. Cu toate acestea, poate fi necesar să adăugați o funcționalitate suplimentară care va rula înainte, după sau chiar în locul funcționalității principale a obiectului.

Soluție

Decoratorul asigură extinderea funcționalității unui obiect fără a defini subclase.

Membrii

O clasă ConcreteComponent este o clasă la care se adaugă o nouă funcționalitate folosind modelul Decorator. În unele cazuri, funcționalitatea de bază este furnizată de clase care derivă din ConcreteComponent. În astfel de cazuri, clasa ConcreteComponentnu mai este concretă, ci abstractă . O clasă abstractă Componentdefinește o interfață pentru utilizarea tuturor acestor clase.

Consecințele

  1. Funcționalitatea adăugată este implementată în obiecte mici. Avantajul este capacitatea de a adăuga dinamic această funcționalitate înainte sau după funcționalitatea principală a ConcreteComponent.
  2. Vă permite să evitați supraîncărcarea cu clase funcționale la nivelurile superioare ale ierarhiei
  3. Decoratorul și componentele sale nu sunt identice

Implementare

Este creată o clasă abstractă care reprezintă atât clasa originală, cât și noile funcții adăugate clasei. În clasele de decorator, funcțiile noi sunt apelate în secvența necesară, fie înainte, fie după apelarea următorului obiect.

Dacă se dorește, rămâne posibilă utilizarea clasei inițiale (fără a extinde funcționalitatea), dacă a fost păstrată o referință la obiectul acesteia.

Note și comentarii

Aplicarea unui șablon

Driverele de filtrare din nucleul Windows ( arhitectura WDM (Windows Driver Model) ) sunt decoratori. În ciuda faptului că WDM este implementat într-un limbaj C non-obiect , acesta arată clar modele de design - un decorator, un lanț de responsabilități și o comandă ( obiect irp ).

Arhitectura COM (Component Object Model) nu suportă moștenirea implementării, în schimb se propune utilizarea decoratorilor (în această arhitectură aceasta se numește „agregare”). În același timp, arhitectura rezolvă (folosind mecanismul pUnkOuter) problema identității obiectului care apare la folosirea decoratorilor - identitatea unui agregat este identitatea decoratorului său cel mai exterior.

Exemple

Kotlin

Un exemplu în Kotlin fun main () { LoggingNotifier ( FancyNotifier ( ConsoleNotifier () ) ). notifică ( "Bună ziua, lume!" ) } interfață Notifier { fun notify ( mesaj : String ) } clasa ConsoleNotifier : Notifier { override fun notify ( mesaj : String ) { println ( mesaj ) } } clasa LoggingNotifier ( private val notifier : Notifier ) : Notifier { override fun notify ( mesaj : String ) { notifier . notify ( mesaj ) println ( " LOG - $ mesaj " ) // Ca un logger } } class FancyNotifier ( private val notifier : Notifier ) : Notifier { override fun notify ( mesaj : String ) { val border = "-" . repetare ( mesaj . lungime ) notificator . notifică ( """ chenar $ mesaj $ chenar $ """ . trimIndent ()) } }

Ruby

Exemplu în Ruby modul DecoratorPattern # Extinde funcționalitatea de bază combinând mai mulți Decoratori class Sursa def initialize ( line ) @line = line end def write_line @line end end # Modulul Decorator abstract Decorator def initialize ( sursa ) @source = sfarsitul sursei def write_line raise NotImplementedError end end # Clasa de decorator de beton Upcaser include Decorator def write_line @source . write_line . sfârşitul majusculului _ # Clasa Decorator de beton Marca temporală include Decorator def write_line " #{ Time . now . strftime ( '%H:%m' ) } #{ @source . write_line } " end end # Clasa Concrete Decorator Datestamper include Decorator def write_line " #{ Time . now . strftime ( '%d.%m.%y' ) } #{ @source . write_line } " end end def sine . run puts '=> Decorator' sursa = sursa . new ( 'Lorem ipsum dolor sit amet' ) pune "Sursa: \n => #{ sursă . write_line } " upcased = Upcaser . new ( sursă ) pune „Majuscule: \n => #{ majuscule . write_line } timestamped = timestamper . new ( sursă ) pune „Timestamped: \n => #{ timestamped . write_line } " datestamped = datestamp . new ( sursă ) pune "Datestamped: \n => #{ datetestamped . write_line } " upcased_timestamped = Timp de timp . new ( Upcaser . new ( sursă )) pune „Upcased and timestamped: \n => #{ upcased_timestamped . write_line } " upcased_datetestamped_timestamped = Datastamped . new ( Timestamper . new ( Upcaser . new ( sursă )))) pune „Majusculat, marcat cu data și marcat cu ora: \n => #{ upcased_datestamped_timestamped . write_line } " datestamped_timestamped = Datastamped . new ( Timestamped . new ( sursă )) pune „Datestamped and timestamped: \n => #{ datestamped_timestamped . write_line } " pune '' end end DecoratorPattern . alerga # => Decorator # Sursa: # => Lorem ipsum dolor sit amet # Upcased: # => LOREM IPSUM DOLOR SIT AMET # Timestamped: # => 18:03 Lorem ipsum dolor sit amet # Datastamped: # => 03/29/ 19 Lorem ipsum dolor sit amet # Upcased and timestamped: # => 18:03 LOREM IPSUM DOLOR SIT AMET # Upcased, datatamped and timestamped: # => 03/29/19 18:03 LOREM IPSUM DOLOR SIT AMET # Datastamped and timestamped: # => 03/29 .19 18:03 Lorem ipsum dolor sit amet

Java

Exemplu Java interfață publică InterfațăComponent { void doOperation (); } clasa MainComponent implementează InterfaceComponent { @Override public void doOperation () { System . afară . print ( "Lumea!" ); } } clasa abstractă Decorator implementează InterfaceComponent { protected InterfaceComponent component ; public Decorator ( InterfaceComponent c ) { component = c ; } @Override public void doOperation () { componentă . doOperation (); } public void newOperation () { System . afară . println ( "Nu face nimic" ); } } clasa DecoratorSpace extinde Decorator { public DecoratorSpace ( InterfaceComponent c ) { super ( c ); } @Override public void doOperation () { System . afară . imprimare ( "" ); super . doOperation (); } @Override public void newOperation () { System . afară . println ( „Operațiune spațială nouă” ); } } clasa DecoratorComma extins Decorator { public DecoratorComma ( InterfaceComponent c ) { super ( c ); } @Override public void doOperation () { System . afară . print ( "," ); super . doOperation (); } @Override public void newOperation () { System . afară . println ( "Operație nouă cu virgulă" ); } } clasa DecoratorHello extins Decorator { public DecoratorHello ( InterfaceComponent c ) { super ( c ); } @Override public void doOperation () { System . afară . print ( "Bună ziua" ); super . doOperation (); } @Override public void newOperation () { System . afară . println ( „O nouă operație salutare” ); } } clasa principal { public static void main ( String ... s ) { Decorator c = nou DecoratorHello ( nou DecoratorComma ( nou DecoratorSpace ( nou MainComponent ()))); c . doOperation (); // Rezultatul programului „Hello, World!” c . newOperation (); // Operațiune nouă salut } }

C#

Exemplu în C# folosind System ; namespace Decorator { class MainApp { static void Main () { // Creați ConcreteComponent și doi Decorators ConcreteComponent c = new ConcreteComponent (); ConcreteDecoratorA dA = nou ConcreteDecoratorA (); ConcreteDecoratorB dB = nou ConcreteDecoratorB (); // Link decoratori dA . SetComponent ( c ); dB . SetComponent ( dA ); d.A._ _ operațiuni (); Consola . writeLine (); dB . operațiuni (); // Așteptați Consola utilizatorului . citește (); } } /// <summary> /// Component - component /// </summary> /// <remarks> /// <li> /// <lu>definiți o interfață pentru obiecte care pot fi dinamic /// suplimentare responsabilități atribuite;</lu> /// </li> /// </remarks> abstract class Component { public abstract void Operațiune (); } /// <summary> /// ConcreteComponent - concrete component /// </summary> /// <remarks> /// <li> /// <lu>definește un obiect care are responsabilități suplimentare</lu> / // </li> /// </remarks> class ConcreteComponent : Component { public override void Operation () { Console . scrie ( "bună ziua" ); } } /// <summary> /// Decorator - decorator /// </summary> /// <remarks> /// <li> /// <lu>stochează o referință la un obiect <see cref="Component" /> și definește o interfață /// corespunzătoare interfeței <see cref="Component"/></lu> /// </li> /// </remarks> abstract class Decorator : Component { protected Component component ; public void SetComponent ( componentă componentă ) { this . component = component ; } public override void Operation () { if ( component != null ) { component . operațiuni (); } } } /// <summary> /// ConcreteDecoratorA - beton decorator /// </summary> /// <remarks> /// <li> /// <lu>Îndeplinește sarcina principală</lu> /// < / li> /// </remarks> class ConcreteDecoratorA : Decorator { public override void Operation () { base . operațiuni (); } } /// <summary> /// ConcreteDecorator - beton decorator /// </summary> /// <remarks> /// <li> /// <lu>Îndeplinește sarcina principală + suplimentar</lu> // / </li> /// </remarks> class ConcreteDecoratorB : Decorator { public override void Operation () { base . operațiuni (); Consola . Scrie ( "Pace!" ); } } }

C++

Exemplu în C++ #include <iostream> #include <memorie> clasa IComponent { public : operație de gol virtual () = 0 ; virtual ~ IComponent (){} }; class Component : public IComponent { public : operațiune virtuală de gol () { std :: cout << "Lumea!" << std :: endl ; } }; clasa DecoratorOne : IComponent public { std :: shared_ptr < IComponent > m_component ; public : DecoratorOne ( std :: shared_ptr < IComponent > component ) : m_component ( component ) {} operațiune virtuală de gol () { std :: cout << ", " ; m_component -> operație (); } }; clasa DecoratorTwo : public IComponent { std :: shared_ptr < IComponent > m_component ; public : DecoratorTwo ( std :: shared_ptr < IComponent > component ) : m_component ( component ) {} operațiune virtuală de gol () { std :: cout << "Bună ziua" ; m_component -> operație (); } }; int main () { DecoratorTwo obj ( std :: make_shared < DecoratorOne > ( std :: make_shared < Component > ())); obj . operare (); // afișează „Hello, World!\n” return 0 ; }

D

Exemplu în limbajul D import std . stdio ; abstract class Figure { protected string name ; șir getInfo (); } class Empty : Figure { override string getInfo () { return null ; } } class Circle : Figure { protected Figure figure ; aceasta ( Figura f ) { figura = f ; nume = „cerc” ; } override string getInfo () { return name ~ figure . getInfo (); } } class Bar : Figure { protected Figure figure ; aceasta ( Figura f ) { figura = f ; nume = "bar" ; } override string getInfo () { return figure . getInfo () ~ nume ; } } void main () { Cifrele figurilor = bară nouă ( cerc nou ( bară nouă ( cerc nou ( gol nou ())))); writeln ( figures.getInfo ( ) ); }

Python

Mai jos este un exemplu de implementare a modelului de proiectare. Există decoratori de funcție și clasă în Python , care au un concept diferit de modelul de design.

Exemplu Python [1] """ Decoratori demonstrați într-o lume a unei grile de 10x10 cu valori 0-255. """ import aleatoriu def s32_to_u16 ( x ): if x < 0 : semn = 0xf000 else : semn = 0 jos = x & 0x00007fff return jos | semn def seed_from_xy ( x , y ): return s32_to_u16 ( x ) | ( s32_to_u16 ( y ) << 16 ) clasa RandomSquare : def __init__ ( s , seed_modifier ): s . seed_modifier = seed_modifier def get ( s , x , y ): seed = seed_from_xy ( x , y ) ^ s . seed_modifier aleatoriu . seed ( seed ) return random . randint ( 0 , 255 ) clasa DataSquare : def __init__ ( s , initial_value = None ): s . data = [ initial_value ] * 10 * 10 def get ( s , x , y ): return s . date [ ( y * 10 ) + x ] # da: acestea sunt toate 10x10 def set ( s , x , y , u ): s . date [ ( y * 10 ) + x ] = u clasa CacheDecorator : def __init__ ( s , decorated ): s . decorated = decorated s . cache = DataSquare () def get ( s , x , y ): dacă s . cache . obține ( x , y ) == Nici unul : s . cache . set ( x , y , s . decorat . get ( x , y ) ) return s . cache . obține ( x , y ) clasa MaxDecorator : def __init__ ( s , decorat , max ): s . decorated = decorated s . max = max def get ( s , x , y ): dacă s . decorat . obține ( x , y ) > s . max : returnare s . randament maxim s . decorat . obține ( x , y ) clasa MinDecorator : def __init__ ( s , decorat , min ): s . decorated = decorated s . min = min def get ( s , x , y ): dacă s . decorat . obține ( x , y ) < s . min : întoarcere s . min return s . decorat . obține ( x , y ) class VisibilityDecorator : def __init__ ( s , decorated ): s . decorat = decorat def get ( s , x , y ): return s . decorat . get ( x , y ) def draw ( s ): for y in range ( 10 ): for x in range ( 10 ): print " %3d " % s . obține ( x , y ), imprimă # Acum, construiește o serie de decoratori: random_square = RandomSquare ( 635 ) random_cache = CacheDecorator ( random_square ) max_filtered = MaxDecorator ( random_cache , 200 ) min_filtered = MinDecorator ( max_filtered , 100 ) final = VisibilityDecorator ( min_filtered ) final . trage ()

Ieșire (rețineți utilizarea unui generator de numere pseudoaleatoare):

100 100 100 100 181 161 125 100 200 200 100 100 200 200 200 200 200 200 200 184 162 100 155 200 200 200 200 200 200 143 100 200 144 2001 143 114 200 166 136 100 _ _ _ _ _ _ _ _ _ _ _ _ _ 19 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 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

Exemplu PHP abstract class AbstractComponent { abstract public function operation (); } clasa ConcreteComponent extinde AbstractComponent { operațiunea funcției publice () { // ... } } abstract class AbstractDecorator extinde AbstractComponent { protected $component ; public function __construct ( AbstractComponent $component ) { $this -> component = $component ; } } class ConcreteDecorator extinde AbstractDecorator { public function operation () { // ... functionalitate extinsa ... $this -> component -> operation (); // ... funcționalitate extinsă ... } } $decoratedComponent = nou ConcreteDecorator ( nou ConcreteComponent () ); $decoratedComponent -> operatie ();

PHP 5

Exemplu PHP5 cel mai des folosit <?php interfață IText { public function show (); } clasa TextHello implementează IText { protected $object ; function public __construct ( IText $text ) { $this -> obiect = $text ; } public function show () { echo 'Hello' ; $this -> obiect -> show (); } } clasa TextWorld implementează IText { protected $object ; function public __construct ( IText $text ) { $this -> obiect = $text ; } public function show () { echo 'world' ; $this -> obiect -> show (); } } clasa TextSpace implementeaza IText { protected $object ; function public __construct ( IText $text ) { $this -> obiect = $text ; } public function show () { echo ' ' ; $this -> obiect -> show (); } } clasa TextEmpty implementează IText { funcția publică arată () { } } $decorator = new TextHello ( new TextSpace ( new TextWorld ( new TextEmpty ()))); $decorator -> show (); // Bună ziua ecou „<br />” . PHP_EOL ; $decorator = new TextWorld ( new TextSpace ( new TextHello ( new TextEmpty ()))); $decorator -> show (); // Salut Lume

CoffeeScript

Exemplu în CoffeeScript # Clasa componente Notebook # Preț de marketing : 500 # $ # Specificații hdd: 320 # GB ram: 4 # GB nucleu: „i5 2.3” # GHz # Clasa decorator NovaNotebook constructor : (produs) -> @preț = produs . preț * 1,3 # Clasa decorator ImportNotebook constructor : (produs) -> @preț = produs . pret * 1,5 # Clasa decorator AppleNotebook constructor : (produs) -> @preț = produs . pret * 2.1 macBookInRussia = nou ImportNotebook nou NovaNotebook nou AppleNotebook nou Consolă Notebook . jurnal ( macBookInRussia .price ) _

JavaScript

Exemplu JavaScript

Modelul de decorator în limbi cu tastare dinamică poate fi utilizat fără interfețe și moștenire OOP tradițională.

Acest exemplu este copiat din versiunea în limba engleză a articolului. Calculul costului cafelei:

// ConcreteComponent (clasă pentru a decora mai târziu) function Coffee () { this . cost = function () { return 1 ; }; } // Decorator A function Milk ( cafea ) { this . cost = function () { return cafea . cost () + 0,5 ; }; } // Funcția Decorator B Whip ( cafea ) { this . cost = function () { return cafea . cost () + 0,7 ; }; } // Decorator C function Sprinkles ( coffee ) { this . cost = function () { return cafea . cost () + 0,2 ; }; } // Poate fi folosit astfel: var coffee = new Milk ( new Whip ( new Sprinkles ( new Coffee ()))); alertă ( cafea.cost ( ) ) ; // Sau mai vizual: var cafea = cafea nouă (); cafea = nou Sprinkles ( cafea ); cafea = bici nou ( cafea ); cafea = nou Lapte ( cafea ); alertă ( cafea.cost ( ) );

Implementarea exemplului C# de mai sus. La ConcreteComponent a fost adăugat un preț variabil local, care se va schimba atât în ​​sine, cât și în decoratori. Numele claselor (cu excepția postfixelor „A” și „B”) sunt aceleași cu numele membrilor șablonului.

function Component () { this . functionare = function () { }; aceasta . getPrice = function () { }; aceasta . setPrice = function () { }; } function ConcreteComponent () { var price = 10 ; aceasta . functionare = function () { price += 4 ; alertă ( "ConcreteComponent. operațiune, preț: " + preț ); }; aceasta . getPrice = function () { return price ; }; aceasta . setPrice = function ( val ) { price = val ; }; } ConcreteComponent . prototip = Componentă nouă (); ConcreteComponent . prototip . constructor = ConcreteComponent ; function Decorator () { var component ; aceasta . setComponent = function ( val ) { component = val ; }; aceasta . getComponent = function () { return component ; }; aceasta . functionare = function () { component . operare (); }; aceasta . getPrice = function () { return component . obține preț (); }; aceasta . setPrice = function ( val ) { component . setprice ( val ); }; } Decorator . prototip = Componentă nouă (); Decorator . prototip . constructor = Decorator ; function ConcreteDecoratorA () { Decorator . apel ( acesta ); var operatie = this . operare ; // referire la metoda definită în Decorator aceasta . functionare = function () { this . setPrice ( this . getPrice () + 3 ); alertă ( "ConcreteDecoratorA. operation, price: " + this . getPrice ()); operare (); }; } function ConcreteDecoratorB () { var duplicate = this ; // referire la obiectul instanțiat (pentru că acest lucru se poate schimba) Decorator . apel ( acesta ); var operatie = this . operare ; // referire la metoda definită în Decorator aceasta . functionare = function () { this . setPrice ( this.getPrice ( ) + 1 ) ; alertă ( "ConcreteDecoratorB. operațiune, preț: " + this . getPrice ()); adăugatComportament (); operare (); }; function addedBehavior () { duplicat . setPrice ( duplicat . getPrice () + 2 ); alertă ( "addedBehavior, preț: " + duplicat . getPrice ()); } } // utilizare c = nou ConcreteComponent (); d1 = nou ConcreteDecoratorA (); d2 = nou ConcreteDecoratorB (); alertă ( "prețul original: " + c . getPrice ()); // zece d1 . setComponent ( c ); d2 . setComponent ( d1 ); d2 . operare (); alertă ( "preț după conversie: " + c . getPrice ()); // douăzeci

VB.NET

Exemplu în VB.NET Decorator spatiu de nume programul clasei Shared Sub Main () ' Creați ConcreteComponent și doi decoratori Dim C ca nou ConcreteComponent () Dim D1 ca nou ConcreteDecoratorA () Dim D2 ca nou ConcreteDecoratorB () ' Referințe pentru decorator D1 . SetComponent ( C ) D2 . SetComponent ( D1 ) D2 . operare () ' Se așteaptă o acțiune din Consola utilizator . Citiți () End Sub termina clasa ''' <summary> ''' Component - component ''' </summary> ''' <remarks> ''' <li> ''' <lu>definiți o interfață pentru obiecte care pot fi alocate dinamic ''' responsabilități suplimentare;</lu> ''' </li> ''' </remarks> MustInherit Class Component Public MustOverride Sub Operation () End Class ''' <summary> ''' ConcreteComponent - concrete component ''' </summary> ''' <remarks> ''' <li> ''' <lu>definește un obiect care are responsabilități suplimentare</lu> ' '' </li> ''' </remarks> Clasa ConcreteComponent moștenește Componenta Consola de suboperație () de anulări publice . WriteLine ( "ConcreteComponent.Operation()" ) End Sub End Class ''' <summary> ''' Decorator - decorator ''' </summary> ''' <remarks> ''' <li> ''' <lu> stochează o referință la un obiect <see cref="Component" /> și definește o interfață „'' corespunzătoare interfeței <see cref="Component"/></lu> ''' </li> ''' </remarks> MustInherit Class Decorator moștenește componenta Componentă protejată ca componentă Public Sub SetComponent ( componenta ByVal ca componentă ) Me . component = component End Sub Public Overscrie suboperațiunea () Dacă componenta nu este nimic , atunci componenta . Operațiunea () End If End Sub End Class ''' <summary> ''' ConcreteDecorator - decoratorul de beton ''' </summary> ''' <remarks> ''' <li> ''' <lu>pune responsabilități suplimentare pe componentă.</lu> '' ' </li> ''' </remarks> Clasa ConcreteDecoratorA Moștenește Decorator Private addedState As String Suboperațiunea publică suprascrie ( ) MyBase . Operațiunea () addedState = Consola „New State” . WriteLine ( "ConcreteDecoratorA.Operation()" ) End Sub End Class ' "ConcreteDecoratorB" Clasa ConcreteDecoratorB moștenește Decorator Suboperațiunea publică suprascrie ( ) MyBase . Operațiune () AddedBehavior () Consola . WriteLine ( "ConcreteDecoratorB.Operation()" ) End Sub Private Sub AddedBehavior () End Sub End Class End Spațiu de nume

Delphi

Delphi și Free Pascal susțin ajutoarele de clasă care fac ca utilizarea modelului decorator să nu fie necesară .

exemplu Delphi programul NoMoreDecorators ; tip TMyObject = procedura de clasă WriteHello ; sfârşitul ; TMyObjectHelper = class helper pentru procedura TMyObject WriteHello ( const Name : string ) ; suprasarcina ; sfârşitul ; procedura TMyObject . Scrie Bună ; începe scrierea ( „Bună ziua” ) ; sfârşitul ; procedura TMyObjectHelper . WriteHello ( const Nume : șir ) ; start writeln ( ' Bună, ' , Nume , '!' ) ; sfârşitul ; var o : TMyObject ; începe o := TMyObject . a crea ; o . Scrie Bună ; o . ScrieBună ziua ( „Jean” ) ; o . Gratuit ; sfârşitul . exemplu Delphi programul DecoratorPattern ; {$APPTYPE CONSOLE} folosește SysUtils ; tip TInterfaceComponent = clasă procedură publică Operare ; virtual ; abstract ; sfârşitul ; tip TConcreteComponent = clasă ( TInterfaceComponent ) procedură publică Operare ; suprascrie ; sfârşitul ; procedura TConcreteComponent . operare ; începe Scrierea ( „nu se poate” ) ; sfârşitul ; tip TDecorator = clasa ( TInterfaceComponent ) private FComponent : TInterfaceComponent ; constructor public Creare ( aComponent : TInterfaceComponent ) ; sfârşitul ; constructor TDecorator . Creare ( aComponent : TInterfaceComponent ) ; începe FComponent := aComponent ; sfârşitul ; tip TBeforeDecorator = clasă ( TDecorator ) procedură publică Operațiune ; suprascrie ; sfârşitul ; procedura TBeforeDecorator . operare ; începe Write ( 'Execute,' ) ; FComponent . operare ; sfârşitul ; tip TAfterDecorator = clasa ( TDecorator ) procedura publica Operatiune ; suprascrie ; sfârşitul ; procedura TAfterDecorator . operare ; începe FComponent . operare ; Scrie ( 'iertare' ) ; sfârşitul ; tip TOverrideDecorator = clasă ( TDecorator ) procedură publică Operare ; suprascrie ; sfârşitul ; procedura TOoverrideDecorator . operare ; începe Scrie ( 'Iubește-te unii pe alții!' ) ; sfârşitul ; var vSameComponent : TInterfaceComponent ; începe vSameComponent := TAfterDecorator . Creare ( TConcreteComponent . Creare ) ; vSameComponent . operare ; // Se va tipări „nu pot ierta” Writeln ; vSameComponent := TBeforeDecorator . Creați ( vSameComponent ) ; vSameComponent . operare ; // Se va imprima „Execută, nu pot ierta” Writeln ; vSameComponent := TOverrideDecorator . Creați ( vSameComponent ) ; vSameComponent . operare ; // Va imprima „Iubește-te unul pe altul!” // De dragul simplității, nu este afișată distrugerea obiectelor Readln ; sfârşitul .

Swift

Exemplu rapid protocol Book { var title : String { get set } var price : Int { get set } func getPrice () -> Int } clasa BookImpl : Book { var title : String = "" var price : Int = 1000 func getPrice () -> Int { return price } } Class DiscountBook : Rezervați { let element : BookImpl var title : String = „Algoritmi de îngrijire” var price : Int = 0 init ( element : BookImpl ) { self . element = element self . titlu = element . titlu de sine . pret = element . preț } // 30% reducere func getPrice () -> Int { return price - ( price * 30 ) / 100 } } // Folosește Decorator let book = BookImpl () let discountBook = DiscountBook ( element : book ) print ( discountBook . getPrice ())

Literatură

  • Alan Shalloway, James R. Trott. Modele de design. O nouă abordare a designului orientat pe obiecte = Modelele de design explicate: O nouă perspectivă asupra designului orientat pe obiecte. - M . : „Williams” , 2002. - S. 288. - ISBN 0-201-71594-5 .
  • Eric Freeman, Elizabeth Freeman. Modele de design = Head First Design Patterns. - Sankt Petersburg. : Petru. — 656 p. - ISBN 978-5-459-00435-9 .

Note

  1. Model Decorator . wiki.python.org . Preluat la 24 octombrie 2021. Arhivat din original la 24 octombrie 2021.

Link -uri