Dekoratér (designový vzor)
Aktuální verze stránky ještě nebyla zkontrolována zkušenými přispěvateli a může se výrazně lišit od
verze recenzované 19. září 2018; kontroly vyžadují
19 úprav .
Dekoratér |
---|
dekoratér |
|
Typ |
strukturální |
Účel |
pro dynamické připojení k objektu dalších povinností |
profesionálové |
- není potřeba vytvářet podtřídy pro rozšíření funkčnosti objektu;
- schopnost dynamicky zahrnout novou funkcionalitu před nebo za hlavní funkcionalitu objektu ConcreteComponent.
|
Související šablony |
Fasáda , adaptér |
Popsáno v Návrhové vzory |
Ano |
Dekorátor je strukturní návrhový vzor navržený tak , aby dynamicky připojoval další chování k objektu . Vzor Decorator poskytuje flexibilní alternativu k praxi podtřídění za účelem rozšíření funkčnosti.
Klíčové vlastnosti
Výzva
Objekt, který má být použit, plní hlavní funkce. Může však být nutné přidat některé další funkce, které poběží před, po nebo dokonce místo hlavní funkce objektu.
Řešení
Dekorátor poskytuje rozšíření funkčnosti objektu bez definování podtříd.
Členové
Třída ConcreteComponent je třída, do které jsou přidány nové funkce pomocí vzoru Decorator. V některých případech je základní funkce poskytována třídami, které jsou odvozeny z ConcreteComponent. V takových případech již třída ConcreteComponentnení konkrétní, ale abstraktní . Abstraktní třída Componentdefinuje rozhraní pro použití všech těchto tříd.
Důsledky
- Přidaná funkce je implementována v malých objektech. Výhodou je možnost dynamicky přidávat tuto funkcionalitu před nebo za hlavní funkcionalitu ConcreteComponent.
- Umožňuje vyhnout se přetížení funkčními třídami na nejvyšších úrovních hierarchie
- Dekoratér a jeho součásti nejsou totožné
Implementace
Vytvoří se abstraktní třída, která představuje původní třídu i nové funkce přidané do třídy. Ve třídách dekorátorů jsou nové funkce volány v požadovaném pořadí, buď před nebo po volání dalšího objektu.
Na přání zůstává možné použít původní třídu (bez rozšíření funkčnosti), pokud byl zachován odkaz na její objekt.
Poznámky a komentáře
- Ačkoli objekt dekorátoru může přidat svou funkčnost před nebo po funkčnosti hlavního objektu, řetězec vytvořených objektů musí vždy končit objektem třídy ConcreteComponent.
- Základní třídy jazyka Java široce využívají vzor Decorator ke zpracování I/O operací.
- Dekorátor i adaptér jsou obaly kolem objektu – ukládají odkaz na zabalený objekt a často mu předají volání metody. Rozdíl mezi dekorátorem a adaptérem je v tom, že adaptér má vnější rozhraní, které se liší od rozhraní zabaleného předmětu a používá se přesně pro spojování různých rozhraní. Na druhou stranu dekoratér má přesně stejné rozhraní a používá se k přidání funkcí.
- K rozšíření funkčnosti třídy je možné použít dekorátory i strategie . Dekorátoři obalují objekt zvenčí, zatímco uvnitř se do něj vkládají strategie přes určitá rozhraní.
- Nevýhodou strategie je, že třída musí být navržena tak, aby umožňovala vkládání strategií, ale dekorátor takovou podporu nevyžaduje.
- Nevýhodou dekorátoru je, že obaluje přesně stejné rozhraní, které je určeno pro vnější svět, což způsobuje zmatek mezi veřejným rozhraním a rozhraním přizpůsobení, což není vždy žádoucí.
Použití šablony
Ovladače filtrů v jádře Windows ( architektura WDM (Windows Driver Model) ) jsou dekorátory. Navzdory skutečnosti, že WDM je implementován v neobjektovém jazyce C , jasně ukazuje návrhové vzory - dekorátor, řetězec odpovědností a příkaz ( irp object ).
Architektura COM (Component Object Model) nepodporuje dědičnost implementace, místo toho se navrhuje používat dekorátory (v této architektuře se tomu říká „agregace“). Architektura zároveň řeší (pomocí mechanismu pUnkOuter) problém identity objektu, který vzniká při použití dekorátorů – identita agregátu je identitou jeho nejkrajnějšího dekoratéra.
Příklady
Kotlin
Příklad v Kotlinu
fun main () {
LoggingNotifier (
FancyNotifier (
ConsoleNotifier ()
)
). upozornit ( „Ahoj, světe!“ )
}
interface Notifier {
fun notify ( message : String )
}
class ConsoleNotifier : Notifier {
override fun notify ( message : String ) {
println ( message )
}
}
class LoggingNotifier ( private val notifier : Notifier ) : Notifier {
override fun notify ( message : String ) {
notifier . notify ( message )
println ( " LOG - $ message " ) // Jako logger
}
}
class FancyNotifier ( private val notifier : Notifier ) : Notifier {
override fun notify ( zpráva : String ) {
val border = "-" . opakování ( délka zprávy ) oznamovatel . _ upozornit ( """ $ ohraničení
$ zpráva
$ hranice
""" . trimIndent ())
}
}
Ruby
Příklad v
Ruby
modul DecoratorPattern
# Rozšiřuje základní funkcionalitu kombinací několika Decoratorů
class Source
def initialize ( line )
@line = line
end
def write_line
@line
end
end
# Abstract Decorator
module Decorator
def initialize ( source )
@source = source
end
def write_line
raise NotImplementedError
end
end
#
Třída dekoratér betonu Upcaser
zahrnuje dekoratér
def write_line
@source . psát_řádek . upcase
end
end
# Třída dekoratér betonu Časové razítko
zahrnuje dekoratér
def write_line
" #{ Time . now . strftime ( '%H:%m' ) } #{ @source . write_line } " end end
#
Třída Beton Decorator Datestamper
zahrnuje Decorator
def write_line
" #{ Time . now . strftime ( '%d.%m.%y' ) } #{ @source . write_line } " end end
def self . spustit
vloží '=> Dekorátor'
zdroj = zdroj . new ( 'Lorem ipsum dolor sit amet' )
vkládá "Zdroj: \n => #{ source . write_line } "
upcase = Upcaser . new ( source )
vloží "Upcased: \n => #{ upcased . write_line } "
timestamped = časové razítko . new ( source )
vloží "Timestamped: \n => #{ timestamped . write_line } "
datestamped = datestamp . new ( source )
vloží "Datestamped: \n => #{ datestamped . write_line } "
upcased_timestamped = Časové razítko . new ( Upcaser . new ( source ))
vloží "Upcased a timestamped: \n => #{ upcased_timestamped . write_line } "
upcased_datestamped_timestamped = Označeno datem . new ( Timestamper . new ( Upcaser . new ( source )))
vloží "Upcased, datestamped a timestamped: \n => #{ upcased_datestamped_timestamped . write_line } "
datestamped_timestamped = Označeno datem . new ( Timestamped . new ( source ))
vloží "Datestamped and timestamped: \n => #{ datestamped_timestamped . write_line } "
ukončí ' '
konec
Vzor dekoratérů . běh
# => Dekorátor
# Zdroj:
# => Lorem ipsum dolor sit amet
# Upcased:
# => LOREM IPSUM DOLOR SIT AMET
# Timestamped:
# => 18:03 Lorem ipsum dolor sit amet
# Datestamped:
# => 03/29/ 19 Lorem ipsum dolor sit amet
# Přepsáno a opatřeno časovým razítkem:
# => 18:03 LOREM IPSUM DOLOR SIT AMET
# Přepsáno, opatřeno datem a časovým razítkem:
# => 29.03.2019 18:03 LOREM IPSUM DOLOR SIT AMET
# Datestamped:
# => 03/29 ,19 18:03 Lorem ipsum dolor sit amet
Java
Příklad Java
public interface Komponenta rozhraní {
void doOperation ();
}
class MainComponent implementuje InterfaceComponent {
@Override
public void doOperation () {
System . ven . tisknout ( "Svět!" );
}
}
abstract class Decorator implementuje InterfaceComponent {
protected InterfaceComponent komponenta ;
public Decorator ( InterfaceComponent c ) {
component = c ;
}
@Override
public void doOperation () {
komponenta . doOperation ();
}
public void newOperation () {
System . ven . println ( "Nedělat nic" );
}
}
class DecoratorSpace rozšiřuje Decorator {
public DecoratorSpace ( InterfaceComponent c ) {
super ( c );
}
@Override
public void doOperation () {
System . ven . tisknout ( "" );
super _ doOperation ();
}
@Override
public void newOperation () {
System . ven . println ( "Nová vesmírná operace" );
}
}
class DecoratorComma rozšiřuje Decorator {
public DecoratorComma ( InterfaceComponent c ) {
super ( c );
}
@Override
public void doOperation () {
System . ven . tisknout ( "," );
super _ doOperation ();
}
@Override
public void newOperation () {
System . ven . println ( "Nová operace s čárkou" );
}
}
class DecoratorHello rozšiřuje Decorator {
public DecoratorAhoj ( InterfaceComponent c ) {
super ( c );
}
@Override
public void doOperation () {
System . ven . tisk ( "Dobrý den" );
super _ doOperation ();
}
@Override
public void newOperation () {
System . ven . println ( "Nová ahoj operace" );
}
}
třída Hlavní {
public static void main ( String ... s ) {
Decorator c = new DecoratorHello ( new DecoratorComma ( new DecoratorSpace ( new MainComponent ())));
c . doOperation (); // Výsledek programu "Ahoj, světe!"
c . newOperation (); // Nová operace ahoj
}
}
C#
Příklad v C#
pomocí System ;
jmenný prostor Dekorátor
{
class MainApp
{
static void Main ()
{
// Vytvoření ConcreteComponent a dvou dekorátorů
ConcreteComponent c = new ConcreteComponent ();
ConcreteDecoratorA dA = new ConcreteDecoratorA ();
ConcreteDecoratorB dB = nový ConcreteDecoratorB ();
// Propojení dekorátorů
dA . SetComponent ( c );
dB . SetComponent ( dA );
d.A. _ operace ();
Konzole . writeLine ();
dB . operace ();
// Počkejte na uživatelskou
konzoli . číst ();
}
}
/// <summary>
/// Komponenta - komponenta
/// </summary>
/// <remarks>
/// <li>
/// <lu>definuje rozhraní pro objekty, které mohou být dynamicky
/// další přidělené odpovědnosti;</lu>
/// </li>
/// </remarks>
abstract class Komponenta
{
public abstract void Operation ();
}
/// <summary>
/// ConcreteComponent - konkrétní komponenta
/// </summary>
/// <remarks>
/// <li>
/// <lu>definuje objekt, který má další povinnosti</lu>
/ // </li>
/// </remarks>
class ConcreteComponent : Komponenta
{
public override void Operation ()
{
Console . napište ( "ahoj" );
}
}
/// <summary>
/// Dekorátor - dekoratér
/// </summary>
/// <remarks>
/// <li>
/// <lu>ukládá odkaz na objekt <viz cref="Component" /> a definuje rozhraní
/// odpovídající rozhraní <viz cref="Component"/></lu>
/// </li>
/// </remarks>
abstract class Decorator : Component
{
protected Component component ;
public void SetComponent ( komponenta komponenty )
{
this . složka = složka ;
}
public override void Operace ()
{
if ( komponenta != null )
{
komponenta . operace ();
}
}
}
/// <summary>
/// ConcreteDecoratorA - dekoratér betonu
/// </summary>
/// <remarks>
/// <li>
/// <lu>Provádí hlavní úkol</lu>
/// < / li>
/// </remarks>
class ConcreteDecoratorA : Decorator
{
public override void Operation ()
{
base . operace ();
}
}
/// <summary>
/// ConcreteDecorator - dekoratér betonu
/// </summary>
/// <remarks>
/// <li>
/// <lu>Provádí hlavní úkol + další</lu>
// / </li>
/// </remarks>
class ConcreteDecoratorB : Decorator
{
public override void Operation ()
{
base . operace ();
Konzole . Napište ( "Mír!" );
}
}
}
C++
Příklad v C++
#include <iostream>
#include <paměť>
class IComponent {
veřejnost :
operace virtuálního zrušení () = 0 ;
virtuální ~ IComponent (){}
};
class Component : public IComponent {
veřejnost :
operace virtuálního zrušení () {
std :: cout << "Svět!" << std :: endl ;
}
};
class DecoratorOne : public IComponent {
std :: shared_ptr < IComponent > m_component ;
veřejnost :
DecoratorOne ( std :: shared_ptr < IComponent > komponenta ) : m_component ( komponenta ) {}
operace virtuálního zrušení () {
std :: cout << ", " ;
m_komponenta -> operace ();
}
};
class DecoratorTwo : public IComponent {
std :: shared_ptr < IComponent > m_component ;
veřejnost :
DecoratorTwo ( std :: shared_ptr < IComponent > komponenta ) : m_component ( komponenta ) {}
operace virtuálního zrušení () {
std :: cout << "Ahoj" ;
m_komponenta -> operace ();
}
};
int main () {
DecoratorTwo obj ( std :: make_shared < DecoratorOne > ( std :: make_shared < Component > ()));
obj _ operace (); // vypíše "Ahoj světe!\n" return 0 ;
}
D
Příklad v jazyce D
import std . stdio ;
abstraktní třída Obrázek
{
název chráněného řetězce ;
string getInfo ();
}
class Empty : Figure
{
override string getInfo ()
{
return null ;
}
}
třída Kruh : Obrázek
{
chráněný obrázek obrázek ;
toto ( obrázek f )
{
obrázek = f ;
jméno = "kruh" ;
}
override string getInfo ()
{
return name ~ figure . getInfo ();
}
}
class Bar : Figure
{
protected Figure figure ;
toto ( obrázek f )
{
obrázek = f ;
name = "bar" ;
}
override string getInfo ()
{
return figure . getInfo () ~ jméno ;
}
}
void main ()
{
Figurky = new Bar ( new Circle ( new Bar ( new Circle ( new Empty ( )))));
writeln ( figure.getInfo ( ) ); }
Python
Níže je uveden příklad implementace návrhového vzoru. V Pythonu jsou dekorátory funkcí a tříd , které mají jiný koncept než návrhový vzor.
Příklad Pythonu
[1]
"""
Demonstrovaní dekoratéři ve světě mřížky 10x10 s hodnotami 0-255.
"""
importovat náhodně
def s32_to_u16 ( x ):
if x < 0 :
znaménko = 0xf000
else :
znaménko = 0
dole = x & 0x00007fff
návrat dole | podepsat
def seed_from_xy ( x , y ): návrat s32_to_u16 ( x ) | ( s32_to_u16 ( y ) << 16 )
class 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
náhodný . semeno ( semeno )
návrat náhodný . randint ( 0 , 255 )
class DataSquare :
def __init__ ( s , počáteční_hodnota = Žádná ):
s . data = [ počáteční_hodnota ] * 10 * 10
def get ( s , x , y ):
return s . data [ ( y * 10 ) + x ] # ano: toto jsou všechny 10x10
def set ( s , x , y , u ):
s . data [ ( y * 10 ) + x ] = u
class CacheDecorator :
def __init__ ( s , zdobené ):
s . ozdobený = ozdobený
s . cache = DataSquare ()
def get ( s , x , y ):
if s . cache . get ( x , y ) == Žádné :
s . cache . set ( x , y , s . zdobené . get ( x , y ) )
return s . cache . získat ( x , y )
class MaxDecorator :
def __init__ ( s , zdobené , max ):
s . ozdobený = ozdobený
s . max = max
def get ( s , x , y ):
if s . zdobené . získat ( x , y ) > s . max :
návrat s . maximální
návratnost s . zdobené . získat ( x , y )
třída MinDecorator :
def __init__ ( s , zdobené , min ):
s . ozdobený = ozdobený
s . min = min
def get ( s , x , y ):
jestliže s . zdobené . get ( x , y ) < s . min :
návrat s . min
návrat s . zdobené . získat ( x , y )
class ViditelnostDekorátor :
def __init__ ( s , zdobené ):
s . dekorovaný = dekorovaný
def get ( s , x , y ):
return s . zdobené . get ( x , y )
def draw ( s ):
pro y v rozsahu ( 10 ):
pro x v rozsahu ( 10 ):
tisk " %3d " % s . získat ( x , y ),
tisknout
# Nyní vytvořte řadu dekoratérů:
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 )
konečná . kreslit ()
Výstup (všimněte si použití generátoru pseudonáhodných čísel):
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 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 1001 1001 1001
PHP
Příklad PHP
abstraktní třída AbstractComponent
{
abstraktní operace veřejné funkce (); }
class ConcreteComponent rozšiřuje AbstractComponent
{
public function operation ()
{
// ...
}
}
abstraktní třída AbstractDecorator rozšiřuje AbstractComponent
{
protected $component ;
public function __construct ( AbstractComponent $component )
{
$this -> component = $component ;
}
}
class ConcreteDecorator rozšiřuje AbstractDecorator
{
public function operation ()
{
// ... rozšířená funkčnost ...
$this -> komponenta -> operace ();
// ... rozšířené funkce ...
}
}
$decoratedComponent = new ConcreteDecorator (
new ConcreteComponent ()
);
$decoratedComponent -> operace ();
PHP 5
Nejčastěji používaný příklad PHP5
<?php
interface IText
{
public function show ();
}
class TextHello implementuje IText
{
protected $object ;
public function __construct ( IText $text ) {
$this -> objekt = $text ;
}
public function show () {
echo 'Ahoj' ;
$this -> objekt -> show ();
}
}
class TextWorld implementuje IText
{
protected $object ;
public function __construct ( IText $text ) {
$this -> objekt = $text ;
}
public function show () {
echo 'svět' ;
$this -> objekt -> show ();
}
}
class TextSpace implementuje IText
{
protected $object ;
public function __construct ( IText $text ) {
$this -> objekt = $text ;
}
public function show () {
echo ' ' ;
$this -> objekt -> show ();
}
}
class TextEmpty implementuje IText
{
public function show () {
}
}
$decorator = new TextHello ( new TextSpace ( new TextWorld ( new TextEmpty ())));
$decorator -> show (); // Hello world
echo '<br />' . PHP_EOL ;
$decorator = new TextWorld ( new TextSpace ( new TextHello ( new TextEmpty ())));
$decorator -> show (); // Ahoj světe
CoffeeScript
Příklad v CoffeeScript
# Notebook třídy komponent # Marketingová cena: 500 # $
# Specifikace
hdd: 320 # GB
RAM: 4 # GB
jádro: 'i5 2.3' # GHz
#
Třída dekoratér Konstruktor NovaNotebooku
: (produkt) ->
@cena = produkt . cena * 1.3
#
Třída Decorator Import
konstruktor Notebooku : (produkt) ->
@cena = produkt . cena * 1.5
#
Třída Decorator Konstruktor AppleNotebooku
: (produkt) ->
@cena = produkt . cena * 2.1
macBookInRussia = nový ImportNotebook nový NovaNotebook nový AppleNotebook nová konzole Notebooku
. log ( macBookInRussia .price ) _
JavaScript
Příklad JavaScriptu
Vzor dekorátoru v dynamicky zadávaných jazycích lze použít bez rozhraní a tradičního dědění OOP.
Tento příklad je zkopírován z anglické verze článku. Výpočet ceny kávy:
// ConcreteComponent (třída k dekoraci později)
function Coffee () {
this . cena = funkce () {
return 1 ;
};
}
// Dekorátor
Funkce Mléko ( káva ) {
this . náklady = funkce () {
vrátit kávu . náklady () + 0,5 ;
};
}
// Decorator B
function Whip ( coffee ) {
this . náklady = funkce () {
vrátit kávu . náklady () + 0,7 ;
};
}
// Decorator C
function Sprinkles ( káva ) {
this . náklady = funkce () {
vrátit kávu . náklady () + 0,2 ;
};
}
// Lze použít takto:
var coffee = new Milk ( new Whip ( new Sprinkles ( new Coffee ())));
upozornění ( coffee.cost ( ) ) ;
// Nebo více vizuálně:
var coffee = new Coffee ();
coffee = new Sprinkles ( coffee );
káva = nový Whip ( káva );
káva = nové Milk ( káva );
upozornění ( coffee.cost ( ) );
Implementace výše uvedeného příkladu C#. Do ConcreteComponent byla přidána lokální variabilní cena, která se bude měnit jak sama o sobě, tak u dekoratérů. Názvy tříd (kromě přípon "A" a "B") jsou stejné jako názvy členů šablony.
function Komponenta () {
this . operace = funkce () { };
toto . getPrice = funkce () { };
toto . setPrice = funkce () { };
}
function ConcreteComponent () {
var cena = 10 ;
toto . operace = funkce () {
cena += 4 ;
upozornění ( "ConcreteComponent. operace, cena: " + cena );
};
toto . getPrice = function () {
return price ;
};
toto . setPrice = function ( val ) {
price = val ;
};
}
ConcreteComponent . prototyp = nová součást ();
ConcreteComponent . prototyp . konstruktor = ConcreteComponent ;
function Decorator () {
var komponenta ;
toto . setComponent = funkce ( val ) {
komponenta = val ;
};
toto . getComponent = function () {
return component ;
};
toto . operace = funkce () {
složka . operace ();
};
toto . getPrice = function () {
return component . getprice ();
};
toto . setPrice = function ( val ) {
komponenta . setprice ( val );
};
}
Dekoratér . prototyp = nová součást ();
Dekoratér . prototyp . konstruktor = Dekorátor ;
function ConcreteDecoratorA () {
Decorator . zavolat ( toto );
var operace = toto . provoz ; // odkaz na metodu definovanou v Dekorátoru
toto . operace = funkce () {
toto . setPrice ( this . getPrice () + 3 );
upozornění ( "operace ConcreteDecoratorA, cena: " + toto . getPrice ());
operace ();
};
}
function ConcreteDecoratorB () {
var duplicate = this ; // odkaz na vytvořený objekt (protože to se může změnit)
Decorator . zavolat ( toto );
var operace = toto . provoz ; // odkaz na metodu definovanou v Dekorátoru
toto . operace = funkce () {
toto . setPrice ( this.getPrice ( ) + 1 ) ; alert ( "operace ConcreteDecoratorB., cena: " + toto . getPrice ()); addBehavior (); operace (); };
function addedBehavior () {
duplicate . setPrice ( duplikát . getPrice () + 2 );
alert ( "addedBehavior, price: " + duplicate . getPrice ());
}
}
// použití
c = new ConcreteComponent ();
d1 = new BetonDecoratorA ();
d2 = new BetonDecoratorB ();
upozornění ( "původní cena: " + c . getPrice ()); // deset
d1 . setComponent ( c );
d2 . setComponent ( d1 );
d2 . operace ();
alert ( "cena po konverzi: " + c . getPrice ()); // dvacet
VB.NET
Příklad ve VB.NET
Dekorátor jmenného prostoru
třídní program
Shared Sub Main ()
' Vytvořit ConcreteComponent a dva dekorátory
Dim C jako nový ConcreteComponent ()
Dim D1 jako nový ConcreteDecoratorA ()
Dim D2 jako nový ConcreteDecoratorB ()
' Odkazy dekoratérů
D1 . SetComponent ( C )
D2 . SetComponent ( D1 )
D2 . operace ()
' Čekání na akci z uživatelské
konzole . Přečíst ()
End Sub
závěrečná třída
''' <summary>
''' Komponenta - komponenta
''' </summary>
''' <remarks>
''' <li>
''' <lu>definuje rozhraní pro objekty, které lze dynamicky
''' přiřazovat další odpovědnosti;</lu>
''' </li>
''' </remarks>
MustInherit Class Component
Public MustOverride Sub Operation ()
End Class
''' <summary>
''' ConcreteComponent - konkrétní komponenta
''' </summary>
''' <remarks>
''' <li>
''' <lu>definuje objekt, který má další povinnosti</lu>
' '' </li>
''' </remarks>
Třída ConcreteComponent
zdědí komponentu
Public Overrides Sub Operation ()
Console . WriteLine ( "ConcreteComponent.Operation()" )
End Sub
End Class
''' <summary>
''' Dekorátor - dekoratér
''' </summary>
''' <remarks>
''' <li>
''' <lu> ukládá odkaz na objekt <viz cref="Component" /> a definuje rozhraní
''' odpovídající rozhraní <see cref="Component"/></lu>
''' </li>
''' </remarks>
MustInherit Class Decorator
Dědí komponentu
Chráněnou komponentu Jako komponentu
Public Sub SetComponent ( komponenta ByVal As Component ) Me . komponenta = komponenta End Sub
Public Overrides Sub Operation ()
If component IsNot Nothing Then
component . Operace ()
End If
End Sub
End Class
''' <summary>
''' ConcreteDecorator - dekorátor betonu
''' </summary>
''' <remarks>
''' <li>
''' <lu>ukládá komponentu další povinnosti.</lu>
'' ' </li>
''' </remarks>
Třída ConcreteDecoratorA
zdědí dekoratér Soukromý přidanýState As String
Veřejné přepisy dílčí operace ()
MyBase . Operace ()
addedState = Konzola "Nový stav"
. WriteLine ( "ConcreteDecoratorA.Operation()" ) End Sub End Class
"Dekoratér betonuB"
Třída ConcreteDecoratorB
zdědí dekoratér
Veřejné přepisy dílčí operace ()
MyBase . Operation ()
AddedBehavior ()
Console . WriteLine ( "ConcreteDecoratorB.Operation()" )
End Sub
Private Sub AddedBehavior ()
End Sub
End Class
End Namespace
Delphi
Delphi a Free Pascal podporují pomocné třídy, díky kterým je použití vzoru dekorátoru zbytečné .
Příklad Delphi
program NoMoreDecorators ;
typ
TMyObject = class
procedure WriteHello ;
konec ;
TMyObjectHelper = pomocník třídy pro proceduru TMyObject WriteHello ( const Name : string ) ; přetížení ; konec ;
procedura TMyObject . Napište Ahoj ;
begin
writeln ( 'Ahoj' ) ;
konec ;
procedura TMyObjectHelper . WriteHello ( const Name : string ) ;
begin
writeln ( 'Dobrý den, ' , Jméno , '!' ) ;
konec ;
var
o : TMyObject ;
begin
o := TMyObject . vytvořit ;
o . Napište Ahoj ;
o . NapišteHello ( 'Jean' ) ;
o . zdarma ;
konec .
Příklad Delphi
program DecoratorPattern ;
{$APPTYPE KONZOLE}
používá
SysUtils ;
typ
TInterfaceComponent = class
public
procedure Operation ; virtuální ; abstraktní ;
konec ;
typ
TConcreteComponent = class ( TInterfaceComponent )
public
procedure Operation ; přepsat ;
konec ;
postup TConcreteComponent . provoz ;
begin
Write ( 'nelze' ) ;
konec ;
typ
TDecorator = class ( TInterfaceComponent )
private
FComponent : TInterfaceComponent ;
veřejný
konstruktor Create ( aComponent : TInterfaceComponent ) ;
konec ;
konstruktor TDecorator . Create ( aComponent : TInterfaceComponent ) ;
begin
FComponent := aComponent ;
konec ;
typ
TBeforeDecorator = class ( TDecorator )
veřejná
procedura Operation ; přepsat ;
konec ;
postup TBeforeDecorator . provoz ;
begin
Zapis ( 'Provést, ' ) ;
FComponent . provoz ;
konec ;
typ
TAfterDecorator = class ( TDecorator )
veřejná
procedura Operace ; přepsat ;
konec ;
postup TAfterDecorator . provoz ;
začít
FComponent . provoz ;
Napište ( 'promiňte' ) ;
konec ;
typ
TOverrideDecorator = class ( TDecorator )
public
procedure Operation ; přepsat ;
konec ;
postup TOverrideDecorator . provoz ;
begin
Napište ( 'Milujte se!' ) ;
konec ;
var
vSameComponent : TInterfaceComponent ;
begin
vSameComponent := TAfterDecorator . Create ( TConcreteComponent . Create ) ;
vSameComponent . provoz ; // Vypíše "nelze prominout"
Writeln ;
vSameComponent := TBeforeDecorator . Create ( vSameComponent ) ;
vSameComponent . provoz ; // Vypíše "Execute, can't pardon"
Writeln ;
vSameComponent := TOverrideDecorator . Create ( vSameComponent ) ;
vSameComponent . provoz ; // Vytiskne "Milujte se!"
// Pro zjednodušení není ukázáno zničení objektů
Readln ;
konec .
Swift
Rychlý příklad
protocol Book {
var title : String { get set }
var price : Int { get set }
func getPrice () -> Int
}
třída BookImpl : Kniha {
var title : String = ""
cena var : Int = 1000
func getPrice () -> Int {
return price
}
}
třída DiscountBook : Book {
let element : BookImpl
var title : String = "Groaming Algorithms"
var price : Int = 0
init ( element : BookImpl ) {
self . element = element
já . titulek = prvek . titulní
já . cena = prvek . cena
}
// 30% prodej
func getPrice () -> Int {
return price - ( price * 30 ) / 100
}
}
// Použijte Dekorátor
let book = BookImpl ()
let slevaBook = DiscountBook ( element : book )
print ( slevaBook . getPrice ())
Literatura
- Alan Shalloway, James R. Trott. Designové vzory. Nový přístup k objektově orientovanému navrhování = vysvětlení návrhových vzorů: Nový pohled na objektově orientovaný design. - M .: "Williams" , 2002. - S. 288. - ISBN 0-201-71594-5 .
- Eric Freeman, Elizabeth Freeman. Design Patterns = Návrhové vzory Head First. - Petrohrad. : Peter. — 656 s. - ISBN 978-5-459-00435-9 .
Poznámky
- ↑ Vzor dekoratérů . wiki.python.org . Získáno 24. října 2021. Archivováno z originálu dne 24. října 2021. (neurčitý)
Odkazy