Dekoratőr (tervminta)
Az oldal jelenlegi verzióját még nem ellenőrizték tapasztalt közreműködők, és jelentősen eltérhet a 2018. szeptember 19-én felülvizsgált
verziótól ; az ellenőrzések 19 szerkesztést igényelnek .
Lakberendező |
---|
lakberendező |
|
Típusú |
szerkezeti |
Célja |
a további kötelezettségek tárgyához való dinamikus kapcsolódáshoz |
profik |
- nincs szükség alosztályok létrehozására az objektum funkcionalitásának kiterjesztéséhez;
- az új funkciók dinamikus felvételének képessége az objektum fő funkciói előtt vagy után ConcreteComponent.
|
Kapcsolódó sablonok |
Homlokzat , Adapter |
Leírása: Tervezési minták |
Igen |
A dekorátor egy szerkezeti tervezési minta , amelyet arra terveztek, hogy dinamikusan összekapcsolja a további viselkedést egy objektummal . A Decorator minta rugalmas alternatívát kínál az alosztályozás gyakorlatához a funkcionalitás kiterjesztése érdekében.
Főbb jellemzők
Kihívás
A fő funkciókat a használni kívánt objektum látja el. Szükséges lehet azonban néhány további funkció hozzáadására, amelyek az objektum fő funkciója előtt, után vagy helyett futnak.
Megoldás
A dekorátor lehetővé teszi egy objektum funkcionalitásának kiterjesztését alosztályok meghatározása nélkül.
Tagok
Az osztály ConcreteComponent olyan osztály, amelyhez a Dekorátor minta használatával új funkciókat adnak hozzá. Egyes esetekben a mögöttes funkcionalitást olyan osztályok biztosítják, amelyek a ConcreteComponent. Ilyen esetekben az osztály ConcreteComponentmár nem konkrét, hanem absztrakt . Egy absztrakt osztály egy interfésztComponent határoz meg ezen osztályok használatához.
Következmények
- A hozzáadott funkcionalitás kisméretű objektumokban valósul meg. Az előny az, hogy ez a funkció dinamikusan hozzáadható a fő funkció előtt vagy után ConcreteComponent.
- Lehetővé teszi, hogy elkerülje a funkcionális osztályokkal való túlterhelést a hierarchia legfelső szintjein
- A dekorátor és alkatrészei nem azonosak
Megvalósítás
Létrejön egy absztrakt osztály, amely az eredeti osztályt és az osztályhoz hozzáadott új függvényeket egyaránt reprezentálja. A dekorátor osztályokban az új függvények a kívánt sorrendben kerülnek meghívásra, a következő objektum meghívása előtt vagy után.
Kívánt esetben továbbra is lehetséges az eredeti osztály használata (a funkcionalitás kiterjesztése nélkül), ha az objektumra való hivatkozás megmaradt.
Megjegyzések és megjegyzések
- Bár egy dekorátor objektum hozzáadhatja funkcionalitását a fő objektum funkcionalitása előtt vagy után, a létrehozott objektumok láncának mindig egy osztályú objektummal kell végződnie ConcreteComponent.
- A Java nyelv alaposztályai széles körben használják a Decorator mintát az I/O műveletek kezelésére.
- Mind a dekorátor, mind az adapter egy objektum körül burkol – hivatkozást tárolnak a becsomagolt objektumra, és gyakran metódushívásokat adnak át neki. A dekorátor és az adapter között az a különbség, hogy az adapter külső interfésszel rendelkezik, amely eltér a becsomagolt objektum interfészétől, és pontosan a különböző interfészek összekapcsolására szolgál. A dekorátor viszont pontosan ugyanazzal a felülettel rendelkezik, és a funkciók hozzáadására szolgál.
- Lehetőség van dekorátorok és stratégiák felhasználására egy osztály funkcionalitásának bővítésére . A dekorátorok kívülről burkolják be az objektumot, míg belül bizonyos interfészeken keresztül stratégiákat illesztenek bele.
- A stratégia hátránya, hogy az osztályt úgy kell megtervezni, hogy lehetővé tegye a stratégiák beillesztését, de a dekoratőrnek nincs szüksége ilyen támogatásra.
- A dekorátor hátránya, hogy pontosan ugyanazt a felületet burkolja be, amit a külvilágnak szántak, ami zavart okoz a nyilvános felület és a testreszabási felület között, ami nem mindig kívánatos.
Sablon alkalmazása
A Windows kernel ( WDM (Windows Driver Model) architektúra ) szűrő-illesztőprogramjai dekorátorok. Annak ellenére, hogy a WDM-et nem objektum C nyelven valósítják meg , világosan megmutatja a tervezési mintákat - a dekorátort, a felelősségi láncot és a parancsot ( irp objektum ).
A COM (Component Object Model) architektúra nem támogatja az implementáció öröklését, helyette dekorátorok használata javasolt (ebben az architektúrában ezt "aggregációnak" nevezik). Ugyanakkor az architektúra megoldja (a pUnkOuter mechanizmus segítségével) a dekorátorok használatakor felmerülő objektum identitásproblémát - az aggregátum identitása a legkülső díszítőjének azonossága.
Példák
Kotlin
Egy példa Kotlinban
fun main () {
LoggingNotifier (
FancyNotifier (
ConsoleNotifier ()
)
). értesíteni ( "Hello, World!" )
}
interface Notifier {
fun notify ( üzenet : String )
}
class ConsoleNotifier : Notifier {
override fun notify ( üzenet : String ) {
println ( üzenet )
}
}
class LoggingNotifier ( privát val notifier : Notifier ) : Notifier {
override fun notify ( üzenet : String ) {
notifier . értesíteni ( üzenet )
println ( "LOG - $ üzenet " ) // Mint egy logger
}
}
class FancyNotifier ( private val notifier : Notifier ) : Notifier {
override fun notify ( message : String ) {
val border = "-" . ismétlés ( üzenet . hossza )
értesítő . értesít ( """
$ border
$ üzenet
$ szegély
""" . trimIndent ())
}
}
Ruby
Példa Rubyban
modul DecoratorPattern
# Kibővíti az alapvető funkciókat több dekorátor kombinálásával
osztály Forrás
def inicializál ( sor )
@sor = sor
vége
def write_line
@sor
vége
vége
# Abstract Decorator
module Decorator
def inicializálás ( forrás )
@ forrás = forrás
vége
def write_line
raise NotImplementedError
end
end
# Concrete Decorator
Class Upcaser
tartalmazza Decorator
def write_line
@forrás . write_line . upcase
end
end
# Concrete Decorator
Class Timestamper
is Decorator
def write_line
" #{ Time . now . strftime ( '%H:%m' ) } #{ @source . write_line } " end end
# Beton Dekorátor
osztály A dátumpecsét tartalmazza a Decoratort
def write_line
" #{ Time . now . strftime ( '%d.%m.%y' ) } #{ @source . write_line } " end end
def self . futás : '=>
Decorator '
forrás = forrás . new ( 'Lorem ipsum dolor sit amet' ) a következőt
teszi : "Forrás: \n => #{ source . write_line } "
upcased = Upcaser . new ( source ) a következőt
teszi : "Feltetve: \n => #{ upcased . write_line } "
timestamper = időbélyegző . new ( source ) a következőt
teszi : "Timestamped: \n => #{ timestamped . write_line } "
datestamped = dátumbélyegző . new ( source )
a "Dátumbélyegzett: \n => #{ datestamped . write_line } "
upcased_timestamped = Időbélyeg . new ( Upcaser . new ( forrás )) a következőt
teszi : "Upcased and timestamped: \n => #{ upcased_timestamped . write_line } "
upcased_datestamped_timestamped = Datestamped . new ( Timestamper . new ( Upcaser . new ( forrás ))) a következőt
teszi : "Upcased, datestamped and timestamped: \n => #{ upcased_datestamped_timestamped . write_line } "
datestamped_timestamped = Datestamped . new ( Timestamped . new ( forrás ))
a "Dátumbélyeggel és időbélyeggel: \n => #{ datestamped_timestamped . write_line } "
„
véget
” tesz
Decorator Pattern . fuss
# => Dekorátor
# Forrás:
# => Lorem ipsum dolor sit amet
# Upcased:
# => LOREM IPSUM DOLOR SIT AMET
# Időbélyegző:
# => 18:03 Lorem ipsum dolor sit amet
# Dátumbélyegzés:
# => 03/29/ 19 Lorem ipsum dolor sit amet
# Kiemelt és időbélyegzett:
# => 18:03 LOREM IPSUM DOLOR SIT AMET
# Felnagyított, dátumbélyeggel és időbélyeggel:
# => 03/29/19 18:03 LOREM IPSUM DOLOR SIT AMET
# Dátumbélyegzett:
# => 03/29 .19 18:03 Lorem ipsum dolor sit amet
Java
Java példa
nyilvános interfész InterfaceComponent {
void doOperation ();
}
osztály MainComponent valósítja meg az InterfaceComponent {
@Override
public void doOperation () {
Rendszer . ki . print ( "Világ!" );
}
}
abstract class Decorator implements InterfaceComponent {
protected InterfaceComponent összetevő ;
public Dekorátor ( InterfaceComponent c ) {
komponens = c ;
}
@Override
public void doOperation () {
komponens . doOperation ();
}
public void newOperation () {
Rendszer . ki . println ( "Ne csinálj semmit" );
}
}
class DecoratorSpace kiterjeszti Decorator {
public DecoratorSpace ( InterfaceComponent c ) {
szuper ( c );
}
@Override
public void doOperation () {
Rendszer . ki . nyomtatás ( "" );
szuper . doOperation ();
}
@Override
public void newOperation () {
Rendszer . ki . println ( "Új űrművelet" );
}
}
class DecoratorComma kiterjeszti Decorator {
public DecoratorComma ( InterfaceComponent c ) {
szuper ( c );
}
@Override
public void doOperation () {
Rendszer . ki . nyomtatás ( "," );
szuper . doOperation ();
}
@Override
public void newOperation () {
Rendszer . ki . println ( "Új vesszőművelet" );
}
}
class DecoratorHello kiterjeszti Decorator {
public DecoratorHello ( InterfaceComponent c ) {
szuper ( c );
}
@Override
public void doOperation () {
Rendszer . ki . print ( "Hello" );
szuper . doOperation ();
}
@Override
public void newOperation () {
Rendszer . ki . println ( "Új hello művelet" );
}
}
class fő {
public static void main ( String ... s ) {
Decorator c = new Decorator Hello ( new DecoratorComma ( new DecoratorSpace ( new MainComponent ())));
c . doOperation (); // A "Hello, World!" program eredménye.
c . newOperation (); // Új hello művelet
}
}
C#
Példa a C#-ban
a rendszer használatával ;
névtér Dekorátor
{
class MainApp
{
static void Main ()
{
// ConcreteComponent és két Dekorátor létrehozása
ConcreteComponent c = new ConcreteComponent ();
ConcreteDecoratorA dA = new ConcreteDecoratorA ();
ConcreteDecoratorB dB = new ConcreteDecoratorB ();
// Linkdekorátorok
dA . SetComponent ( c );
dB . SetComponent ( dA );
d.A. _ műveletek ();
Konzol . writeLine ();
dB . műveletek ();
// Várja meg a felhasználói
konzolt . olvasni ();
}
}
/// <summary>
/// Komponens - összetevő
/// </summary>
/// <remarks>
/// <li>
/// <lu>interfész definiálása az objektumok számára, amelyek dinamikusan
/// kiegészítők kiosztott felelősségek;</lu>
/// </li>
/// </remarks>
abstract class Component
{
public abstract void Művelet ();
}
/// <summary>
/// ConcreteComponent - konkrét összetevő
/// </summary>
/// <remarks>
/// <li>
/// <lu>egy olyan objektumot határoz meg, amelynek további felelősségei vannak</lu>
/ // </li>
/// </remarks>
class ConcreteComponent : Component
{
public override void Művelet ()
{
Konzol . írás ( "hello" );
}
}
/// <summary>
/// Dekorátor - lakberendező
/// </summary>
/// <remarks>
/// <li>
/// <lu>tárol egy hivatkozást egy objektumra <lásd cref="Component" /> és meghatároz egy interfészt
/// az interfésznek megfelelő <lásd cref="Component"/></lu>
/// </li>
/// </remarks>
abstract class Decorator : Component
{
protected Komponens komponens ;
public void SetComponent ( Component komponens )
{
this . komponens = komponens ;
}
public override void Művelet ()
{
if ( komponens != null )
{
komponens . műveletek ();
}
}
}
/// <summary>
/// ConcreteDecoratorA - betondekorátor
/// </summary>
/// <remarks>
/// <li>
/// <lu>Elvégzi a fő feladatot</lu>
/// < / li>
/// </remarks>
class ConcreteDecoratorA : Decorator
{
public override void Művelet ()
{
base . műveletek ();
}
}
/// <summary>
/// ConcreteDecorator - betondekorátor
/// </summary>
/// <remarks>
/// <li>
/// <lu>Elvégzi a fő feladatot + kiegészítő</lu>
// / </li>
/// </remarks>
class ConcreteDecoratorB : Decorator
{
public override void Művelet ()
{
base . műveletek ();
Konzol . Írj ( "Béke!" );
}
}
}
C++
Példa C++ nyelven
#include <iostream>
#include <memória>
class IComponent {
nyilvános :
virtuális üres művelet () = 0 ;
virtuális ~ IComponent (){}
};
class komponens : public IComponent {
nyilvános :
virtuális void művelet () {
std :: cout << "Világ!" << std :: endl ;
}
};
class DecoratorOne : public IComponent {
std :: megosztott_ptr < IComponent > m_component ;
nyilvános :
DecoratorOne ( std :: megosztott_ptr < IComponent > összetevő ) : m_component ( komponens ) {}
virtuális void művelet () {
std :: cout << ", " ;
m_komponens -> művelet ();
}
};
class DecoratorTwo : public IComponent {
std :: megosztott_ptr < IComponent > m_component ;
nyilvános :
DecoratorTwo ( std :: shared_ptr < IComponent > komponens ) : m_component ( komponens ) {}
virtuális void művelet () {
std :: cout << "Hello" ;
m_komponens -> művelet ();
}
};
int main () {
DecoratorTwo obj ( std :: make_shared < DecoratorOne > ( std :: make_shared < Component > ()));
obj . művelet (); // kiírja: "Hello, World!\n" return 0 ;
}
D
Példa D nyelven
import std . stdio ;
absztrakt osztály Figure
{
protected string name ;
string getInfo ();
}
class Empty : Figure
{
override string getInfo ()
{
return null ;
}
}
osztály Kör : ábra
{
védett ábra ábra ;
ez ( f ábra ) { ábra = f ; név = "kör" ; }
override string getInfo ()
{
return name ~ ábra . getInfo ();
}
}
class Bar : ábra
{
védett ábra ábra ;
ez ( f ábra ) { ábra = f ; név = "bár" ; }
override string getInfo ()
{
return ábra . getInfo () ~ név ;
}
}
void main ()
{
Ábrafigurák = new Bar ( new Circle ( new Circle ( new Circle ( new Empty ( ) )))));
writeln ( figures.getInfo ( ) ); }
Python
Az alábbiakban egy példa látható a tervezési mintára. A Pythonban vannak funkció- és osztálydekorátorok , amelyek koncepciója eltér a tervezési mintától.
Python példa [1]
"""
Demonstrátorok egy 10x10-es 0-255 értékrács világában.
"""
véletlenszerű importálás
def s32_to_u16 ( x ):
ha x < 0 :
előjel = 0xf000
else :
előjel = 0
alsó = x & 0x00007fff
vissza lent | jel
def seed_from_xy ( x , y ): return s32_to_u16 ( x ) | ( s32_to_u16 ( y ) << 16 )
osztály 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
véletlenszerű . seed ( seed )
return random . randint ( 0 , 255 )
osztály DataSquare :
def __init__ ( s , kezdeti_érték = Nincs ):
s . data = [ kezdeti_érték ] * 10 * 10
def get ( s , x , y ):
return s . adatok [ ( y * 10 ) + x ] # igen: ezek mind 10x10
def halmazok ( s , x , y , u ):
s . adat [ ( y * 10 ) + x ] = u
osztály CacheDecorator :
def __init__ ( s , díszített ):
s . díszített = díszített
s . cache = DataSquare ()
def get ( s , x , y ):
if s . gyorsítótár . get ( x , y ) == Nincs :
s . gyorsítótár . set ( x , y , s . díszített . get ( x , y ) )
return s . gyorsítótár . kap ( x , y )
osztály MaxDecorator :
def __init__ ( s , díszített , max ):
s . díszített = díszített
s . max = max
def get ( s , x , y ):
ha s . díszített . get ( x , y ) > s . max :
visszatérés s . max
megtérülés s . díszített . kap ( x , y )
osztály MinDecorator :
def __init__ ( s , díszített , min ):
s . díszített = díszített
s . min = min
def get ( s , x , y ):
ha s . díszített . get ( x , y ) < s . min :
visszatérés s . min
visszatérés s . díszített . kap ( x , y )
osztály LáthatóságDekorátor :
def __init__ ( s , díszített ):
s . díszített = díszített
def get ( s , x , y ):
return s . díszített . get ( x , y )
def draw ( s ):
y esetén a tartományban ( 10 ): x esetén a tartományban ( 10 ): " %3d " % s nyomtatása . kap ( x , y ), nyomtat
# Most állítsa fel a dekorátorok csővezetékét:
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 )
végső . húzni ()
Kimenet (figyelem az álvéletlen számgenerátor használatára):
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 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144 161 100 200 200 200 200 190 125 100 177 150 200 100 175 111 195 195 128 100 100 200 200 200 200 200 129 105 112 100 101 200 200 100 100 100 100 101 120 180 200 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 példa
abstract class AbstractComponent
{
abstract public function operation ();
}
class ConcreteComponent kiterjeszti AbstractComponent
{
public function operation ()
{
// ...
}
}
abstract class AbstractDecorator expands AbstractComponent
{
protected $component ;
public function __construct ( AbstractComponent $component )
{
$this -> komponens = $komponens ;
}
}
class ConcreteDecorator expands AbstractDecorator
{
public function operation ()
{
// ... kiterjesztett funkcionalitás ...
$this -> összetevő -> művelet ();
// ... bővített funkcionalitás ...
}
}
$decoratedComponent = new ConcreteDecorator (
new ConcreteComponent ()
);
$decoratedComponent -> művelet ();
PHP 5
A leggyakrabban használt PHP5 példa
<?php
interface IText
{
public function show ();
}
class TextHello implementálja az IText
{
protected $object ;
public function __construct ( IText $szöveg ) {
$this -> object = $szöveg ;
}
public function show () {
echo 'Hello' ;
$this -> object -> show ();
}
}
class TextWorld implementálja az IText
{
protected $object ;
public function __construct ( IText $szöveg ) {
$this -> object = $szöveg ;
}
public function show () {
echo 'világ' ;
$this -> object -> show ();
}
}
class TextSpace implementálja az IText
{
protected $object ;
public function __construct ( IText $szöveg ) {
$this -> object = $szöveg ;
}
public function show () {
echo ' ' ;
$this -> object -> show ();
}
}
class TextEmpty implementálja az IText
{
public function show () {
}
}
$decorator = new TextHello ( new TextSpace ( new TextWorld ( new TextEmpty ())));
$dekorátor -> show (); // Hello world
echo '<br />' . PHP_EOL ;
$decorator = new TextWorld ( new TextSpace ( new TextHello ( new TextEmpty ())));
$dekorátor -> show (); // Helló Világ
CoffeeScript
Példa a CoffeeScriptben
# Alkatrész
osztály Notebook
# Marketing
ár: 500 # $
# Műszaki adatok
hdd : 320 # GB
ram : 4 # GB
mag : 'i5 2.3' # GHz
# Dekorátor
osztály NovaNotebook
konstruktor : (termék) -> @ár
= termék . ár * 1.3
# Dekorátor
osztály ImportNotebook
konstruktor : (termék) -> @ár
= termék . ár * 1,5
# Dekorátor
osztály AppleNotebook
konstruktor : (termék) -> @ár
= termék . ár * 2.1
macBookInRussia = új ImportNotebook új NovaNotebook új AppleNotebook új Notebook
konzol . log ( macBookInRussia .price ) _
JavaScript
JavaScript példa
A dinamikusan tipizált nyelvek díszítőmintája interfészek és hagyományos OOP öröklődés nélkül használható.
Ezt a példát a cikk angol nyelvű változatából másoltuk. A kávé árának kiszámítása:
// ConcreteComponent (osztály későbbi díszítéshez)
function Coffee () {
this . költség = függvény () {
return 1 ;
};
}
// Dekorátor A
funkció Tej ( kávé ) {
this . költség = függvény () {
return coffee . költség () + 0,5 ;
};
}
// Dekorátor B
funkció Whip ( kávé ) {
this . költség = függvény () {
return coffee . költség () + 0,7 ;
};
}
// Decorator C
function Sprinkles ( kávé ) {
this . költség = függvény () {
return coffee . költség () + 0,2 ;
};
}
// Így használható:
var kávé = new Milk ( new Whip ( new Sprinkles ( new Coffee ())));
figyelmeztetés ( kávé.költség ( ) ) ;
// Vagy inkább vizuálisan:
var coffee = new Coffee ();
kávé = új Sprinkles ( kávé );
kávé = új Whip ( kávé );
kávé = új Tej ( kávé );
riasztás ( kávé.költség ( ) );
A fenti C# példa megvalósítása. A ConcreteComponent egy helyi változó árat adtak hozzá, ami önmagában és a dekorátorokban is változni fog. Az osztálynevek (az "A" és "B" utótag kivételével) megegyeznek a sablontagok nevével.
function Komponens () {
this . művelet = függvény () { };
ezt . getPrice = függvény () { };
ezt . setPrice = függvény () { };
}
function ConcreteComponent () {
var ár = 10 ;
ezt . művelet = függvény () {
ár += 4 ;
alert ( "ConcreteComponent. művelet, ár: " + ár );
};
ezt . getPrice = function () {
visszatérési ár ;
};
ezt . setPrice = function ( érték ) {
ár = érték ;
};
}
ConcreteComponent . prototípus = new Component ();
ConcreteComponent . prototípus . konstruktor = ConcreteComponent ;
function Dekorátor () {
var összetevő ;
ezt . setComponent = function ( val ) {
komponens = érték ;
};
ezt . getComponent = function () {
return komponens ;
};
ezt . művelet = function () {
komponens . művelet ();
};
ezt . getPrice = function () {
return komponens . getprice ();
};
ezt . setPrice = function ( val ) {
komponens . setprice ( val );
};
}
Dekoratőr . prototípus = new Component ();
Dekoratőr . prototípus . konstruktor = Dekorátor ;
function ConcreteDecoratorA () {
Dekorátor . hívja ( ezt );
var művelet = ez . működés ; // hivatkozás a Dekorátorban definiált módszerre
ezt . művelet = function () {
this . setPrice ( ez . getPrice () + 3 );
alert ( "ConcreteDecoratorA. művelet, ár: " + ez . getPrice ());
művelet ();
};
}
function ConcreteDecoratorB () {
var duplicate = this ; // hivatkozás a példányosított objektumra (mert ez változhat)
Decorator . hívja ( ezt );
var művelet = ez . működés ; // hivatkozás a Dekorátorban definiált módszerre
ezt . művelet = function () {
this . setPrice ( this.getPrice ( ) + 1 ) ; alert ( "ConcreteDecoratorB. művelet, ár: " + ez . getPrice ()); hozzáadva Viselkedés (); művelet (); };
function addedBehavior () {
duplicate . setPrice ( duplicate . getPrice () + 2 );
alert ( "addedBehavior, price: " + duplicate . getPrice ());
}
}
// használat
c = új ConcreteComponent ();
d1 = új ConcreteDecoratorA ();
d2 = új BetonDekorátorB ();
alert ( "eredeti ár: " + c . getPrice ()); // tíz
d1 . setComponent ( c );
d2 . setComponent ( d1 );
d2 . művelet ();
alert ( "ár konverzió után: " + c . getPrice ()); // húsz
VB.NET
Példa a VB.NET-ben
Névtér dekorátor
osztály programja
Megosztott al - fő ()
' ConcreteComponent és két dekorátor létrehozása
Dim C mint új ConcreteComponent ()
Dim D1 mint Új ConcreteDecoratorA ()
Dim D2 Mint New ConcreteDecoratorB ()
" Lakberendező hivatkozások
D1 . SetComponent ( C )
D2 . SetComponent ( D1 )
D2 . művelet ()
" Várakozás a felhasználói
konzol műveletére . Olvassa el ()
End Sub
végi osztály
'''' <summary>
'''' Komponens - komponens
'''' </summary>
''' <remarks>
''' <li>
''' <lu>interfész meghatározása az objektumok számára, amelyek dinamikusan
''' hozzárendelhetők további felelősségek;</lu>
''' </li> ''' <
/ remarks>
Must Inherit Class Component
Public MustOverride Sub Operation ()
Végosztály
'''' <summary>
''' ConcreteComponent - konkrét összetevő
''' </summary>
''' <remarks>
''' <li>
''' <lu>egy objektumot határoz meg, amely további felelősségekkel rendelkezik</lu>
' '' </li>
''' </remarks> A
ConcreteComponent osztály örökli a komponenst
Nyilvános felülbírálja az alműveleteket () Konzol . WriteLine ( "ConcreteComponent.Operation()" ) End Sub End Class
''' <summary>
''' Dekoratőr - lakberendező
''' </summary>
''' <remarks>
''' <li>
''' <lu> hivatkozást tárol egy objektumra <lásd cref="Alkatrész"
/ > és definiál egy interfészt ' ' '
' , amely megfelel a következőnek
Public Sub SetComponent ( ByVal komponens As Component )
Me . komponens = komponens
End Sub
Nyilvános felülbírálja az alműveletet () Ha a komponens nem semmi Akkor a komponens . Művelet () End If End Sub End Class
'''' <summary>
''' ConcreteDecorator – a betondekorátor
''' </summary>
''' <remarks>
''' <li>
''' <lu>további felelősséget ró az alkatrészre.</lu>
'' </li>
' ' ' < / remarks >
Osztály ConcreteDecorator
Nyilvános felülbírálja az alműveletet () MyBase . Művelet () addedState = "Új állapot" konzol . WriteLine ( "ConcreteDecoratorA.Operation()" ) End Sub End Class
"BetonDekorátorB"
A ConcreteDecoratorB
osztály a lakberendezőt örökli
Nyilvános felülbírálja az alműveletet () MyBase . Művelet () AddedBehavior () Konzol . WriteLine ( "ConcreteDecoratorB.Operation()" ) End Sub
Privát Sub AddedBehavior ()
End Sub
End Class
End névtér
Delphi
Delphi és Free Pascal támogató osztálysegítők, amelyek szükségtelenné teszik a díszítőminta használatát .
Delphi példa
program NoMoreDecorators ;
type
TMyObject = osztályeljárás
WriteHello ; _ vége ;
TMyObjectHelper = osztálysegéd a TMyObject eljáráshoz WriteHello ( const Név : string ) ; _ túlterhelés ; vége ;
eljárás TMyObject . Írj Hello ;
begin
writeln ( 'Hello' ) ;
vége ;
eljárás TMyObjectHelper . WriteHello ( const Név : string ) ;
begin
writeln ( 'Szia, ' , Név , '!' ) ;
vége ;
var
o : TMyObject ;
begin
o := TMyObject . létrehozni ;
o . Írj Hello ;
o . WriteHello ( 'Jean' ) ;
o . Ingyenes ;
vége .
Delphi példa
program DecoratorPattern ;
{$APPTYPE CONSOLE}
SysUtils-t használ ;
type
TInterfaceComponent = osztály
nyilvános
eljárás Művelet ; virtuális ; absztrakt ;
vége ;
típus
TConcreteComponent = osztály ( TInterfaceComponent )
nyilvános
eljárás Művelet ; felülbírálni ;
vége ;
eljárás TConcreteComponent . működés ;
begin
Write ( 'nem lehet' ) ;
vége ;
típus
TDecorator = osztály ( TInterfaceComponent )
private
FComponent : TInterfaceComponent ;
public
konstruktor Create ( aComponent : TInterfaceComponent ) ;
vége ;
konstruktor TDecorator . Create ( aComponent : TInterfaceComponent ) ;
begin
FComponent := aComponent ;
vége ;
típus
TBeforeDecorator = osztály ( TDecorator )
nyilvános
eljárás Művelet ; felülbírálni ;
vége ;
eljárás TBeforeDecorator . működés ;
begin
Write ( 'Végrehajtás,' ) ;
FComponent . működés ;
vége ;
típus
TAfterDecorator = osztály ( TDecorator )
nyilvános
eljárás Művelet ; felülbírálni ;
vége ;
eljárás TAfterDecorator . működés ;
kezdje el
az FComponent . működés ;
Írj ( ' elnézést' ) ;
vége ;
típus
TOverrideDecorator = osztály ( TDecorator )
nyilvános
eljárás Művelet ; felülbírálni ;
vége ;
eljárás TOverrideDecorator . működés ;
begin
Write ( 'Szeressétek egymást!' ) ;
vége ;
var
vSameComponent : TInterfaceComponent ;
begin
vSameComponent := TAfterDecorator . Create ( TConcreteComponent . Create ) ;
vSameComponent . működés ; // Kinyomtatja, hogy "nem tud pardon"
Writeln ;
vSameComponent := TBeforeDecorator . Create ( vSameComponent ) ;
vSameComponent . működés ; // Kinyomtatja: "Execute, can't pardon"
Writeln ;
vSameComponent := TOverrideDecorator . Create ( vSameComponent ) ;
vSameComponent . működés ; // Kinyomtatja a "Szeressétek egymást!"
// Az egyszerűség kedvéért a tárgyak pusztulását nem mutatjuk be
Readln ;
vége .
Swift
Swift példa
protokoll Könyv {
var title : String { get set }
var price : Int { get set }
func getPrice () -> Int
}
class BookImpl : Book {
var title : String = ""
var price : Int = 1000
func getPrice () - > Int {
visszáru }
}
osztály Kedvezménykönyv : Könyv {
let elem : BookImpl
var title : String = "Groaming Algorithms"
var price : Int = 0
init ( elem : BookImpl ) {
self . elem = elem
self . cím = elem . cím
én . ár = elem . ár
}
// 30% eladás
func getPrice () -> Int {
return price - ( ár * 30 ) / 100
}
}
// Decorator használata
let book = BookImpl ()
let discountKönyv = KedvezményKönyv ( elem : könyv )
print ( akcióKönyv . getPrice ())
Irodalom
- Alan Shalloway, James R. Trott. Tervezési minták. Az objektum-orientált tervezés új megközelítése = Design Patterns Explained: Új perspektíva az objektum-orientált tervezéshez. - M . : "Williams" , 2002. - S. 288. - ISBN 0-201-71594-5 .
- Eric Freeman, Elizabeth Freeman. Tervezési minták = Head First Design Patterns. - Szentpétervár. : Péter. — 656 p. - ISBN 978-5-459-00435-9 .
Jegyzetek
- ↑ Dekorátor minta . wiki.python.org . Letöltve: 2021. október 24. Az eredetiből archiválva : 2021. október 24.. (határozatlan)
Linkek