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
- 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.
- Vă permite să evitați supraîncărcarea cu clase funcționale la nivelurile superioare ale ierarhiei
- 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
- Deși un obiect de decorare își poate adăuga funcționalitatea înainte sau după funcționalitatea obiectului principal, lanțul de obiecte creat trebuie întotdeauna să se încheie cu un obiect de clasă ConcreteComponent.
- Clasele de bază ale limbajului Java folosesc pe scară largă modelul Decorator pentru a gestiona operațiunile I/O.
- Atât decoratorul, cât și adaptorul sunt învelișuri în jurul unui obiect - stochează o referință la obiectul înfășurat și adesea îi transmit apeluri de metodă. Diferența dintre un decorator și un adaptor este că adaptorul are o interfață externă care este diferită de interfața obiectului înfășurat și este folosit tocmai pentru îmbinarea diferitelor interfețe. Decoratorul, pe de altă parte, are exact aceeași interfață și este folosit pentru a adăuga funcționalitate.
- Este posibil să folosiți atât decoratori, cât și strategii pentru a extinde funcționalitatea unei clase . Decoratorii înfășoară obiectul din exterior, în timp ce strategiile sunt introduse în el în interior prin anumite interfețe.
- Dezavantajul strategiei este că clasa trebuie concepută pentru a permite inserarea strategiilor, dar decoratorul nu necesită un astfel de sprijin.
- Dezavantajul decoratorului este că înfășoară exact aceeași interfață care este destinată lumii exterioare, ceea ce provoacă confuzie între interfața publică și interfața de personalizare, ceea ce nu este întotdeauna de dorit.
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
- ↑ Model Decorator . wiki.python.org . Preluat la 24 octombrie 2021. Arhivat din original la 24 octombrie 2021. (nedefinit)
Link -uri