Sisustaja (suunnittelukuvio)

Kokeneet kirjoittajat eivät ole vielä tarkistaneet sivun nykyistä versiota, ja se voi poiketa merkittävästi 19. syyskuuta 2018 tarkistetusta versiosta . tarkastukset vaativat 19 muokkausta .
Sisustusarkkitehti
sisustusarkkitehti
Tyyppi rakenteellinen
Tarkoitus dynaamista yhteyttä lisävelvoitteiden kohteeseen
Plussat
  • ei tarvitse luoda alaluokkia objektin toiminnallisuuden laajentamiseksi;
  • kyky sisällyttää dynaamisesti uusia toimintoja ennen kohteen päätoimintoa tai sen jälkeen ConcreteComponent.
Aiheeseen liittyvät mallit Julkisivu , sovitin
Kuvattu suunnittelukuvioissa Joo

Sisustaja on rakennesuunnittelumalli , joka on  suunniteltu yhdistämään dynaamisesti lisäkäyttäytymistä esineeseen . Decorator-kuvio tarjoaa joustavan vaihtoehdon alaluokkien käytännölle toiminnallisuuden laajentamiseksi.

Tärkeimmät ominaisuudet

Haaste

Esine, jota on tarkoitus käyttää, suorittaa päätoiminnot. Siihen voi kuitenkin olla tarpeen lisätä joitain lisätoimintoja, jotka toimivat ennen, jälkeen tai jopa objektin päätoiminnon sijasta.

Ratkaisu

Sisustaja mahdollistaa kohteen toiminnallisuuden laajentamisen ilman alaluokkia.

Jäsenet

Luokka ConcreteComponent on luokka, johon lisätään uusia toimintoja Decorator-kuvion avulla. Joissakin tapauksissa taustalla olevat toiminnot tarjoavat luokat, jotka ovat peräisin ConcreteComponent. Tällaisissa tapauksissa luokka ConcreteComponentei ole enää konkreettinen, vaan abstrakti . Abstrakti luokka Componentmäärittelee käyttöliittymän kaikkien näiden luokkien käyttämiseen.

Seuraukset

  1. Lisätty toiminnallisuus on toteutettu pienissä objekteissa. Etuna on kyky lisätä tämä toiminto dynaamisesti ennen päätoimintoa tai sen jälkeen ConcreteComponent.
  2. Voit välttää ylikuormituksen toiminnallisilla luokilla hierarkian ylimmillä tasoilla
  3. Sisustus ja sen osat eivät ole identtisiä

Toteutus

Luodaan abstrakti luokka, joka edustaa sekä alkuperäistä luokkaa että luokkaan lisättyjä uusia funktioita. Sisustusluokissa uudet funktiot kutsutaan vaaditussa järjestyksessä joko ennen seuraavan objektin kutsumista tai sen jälkeen.

Haluttaessa on edelleen mahdollista käyttää alkuperäistä luokkaa (toiminnallisuutta laajentamatta), jos viittaus sen objektiin on säilytetty.

Huomautuksia ja kommentteja

Mallin käyttäminen

Windows -ytimen suodatinohjaimet ( WDM (Windows Driver Model) -arkkitehtuuri ) ovat koristeita. Huolimatta siitä, että WDM on toteutettu ei-objekti C -kielellä , se näyttää selkeästi suunnittelumallit - sisustajan, vastuuketjun ja komennon ( irp- objekti ).

COM (Component Object Model) -arkkitehtuuri ei tue toteutuksen periytymistä, vaan sen sijaan ehdotetaan käytettäväksi koristeita (tässä arkkitehtuurissa tätä kutsutaan "aggregaatioksi"). Samalla arkkitehtuuri ratkaisee (pUnkOuter-mekanismin avulla) sisustajia käytettäessä esiin tulevan objektin identiteettiongelman - aggregaatin identiteetti on sen uloimman sisustajan identiteetti.

Esimerkkejä

Kotlin

Esimerkki Kotlinista fun main () { LoggingNotifier ( FancyNotifier ( ConsoleNotifier () ) ). ilmoittaa ( "Hei, maailma!" ) } käyttöliittymän ilmoittaja { hauska ilmoitus ( viesti : merkkijono ) } luokka ConsoleNotifier : Notifier { ohita hauska ilmoitus ( viesti : merkkijono ) { println ( viesti ) } } luokka LoggingNotifier ( yksityinen val notifier : Notifier ) : Ilmoittaja { ohita hauska ilmoitus ( viesti : String ) { ilmoitus . ilmoittaa ( viesti ) println ( "LOG - $ viesti " ) // Kuin logger } } class FancyNotifier ( yksityinen val notifier : Notifier ) : Notifier { ohita hauska ilmoitus ( viesti : String ) { val border = " - " . toista ( viesti . pituus ) ilmoitus . notify ( """ $ border $ viesti $ raja """ . trimIndent ()) } }

Ruby

Esimerkki Rubyssa moduuli DecoratorPattern # Laajentaa perustoimintoja yhdistämällä useita koristeita luokka Lähde def alustaa ( rivi ) @rivi = rivin loppu def write_line @rivin loppu _ # Abstract Decorator module Decorator def alustus ( lähde ) @ lähde = lähde loppu def write_line raise NotImplementedError end end # Concrete Decorator Class Upcaser sisältää Decoratorin def write_line @source . kirjoitusrivi . upcase loppu _ # Concrete Decorator Class Timestamper sisältää Decoratorin def write_line " #{ Aika . nyt . strftime ( '%H:%m' ) } #{ @ lähde . write_line } " end end # Concrete Decorator Class Datestamper sisältää Decoratorin def write_line " #{ Aika . nyt . strftime ( '%d.%m.%y' ) } #{ @source . write_line } " end end itsevarmasti . _ run laittaa '=> sisustaja' lähde = lähde . new ( 'Lorem ipsum dolor sit amet' ) laittaa "Lähde: \n => #{ source . write_line } " ylöskirjoitettu = Upcaser . new ( lähde ) laittaa "Upcased: \n => #{ upcased . write_line } " aikaleima = aikaleima . new ( lähde ) laittaa "Timestamped: \n => #{ timestamped . write_line } " päivämääräleima = päivämääräleima . new ( lähde ) laittaa "Päiväleima: \n => #{ datestamped . write_line } " upcased_timestamped = Aikaleima . new ( Upcaser . new ( lähde )) laittaa "Upcased and timestamped: \n => #{ upcased_timestamped . write_line } " upcased_datestamped_timestamped = Päiväysleimattu . new ( Timestamper . new ( Upcaser . new ( lähde ))) laittaa "Upcased, datestamped ja timestamped: \n => #{ upcased_datestamped_timestamped . write_line } " datestamped_timestamped = Päivämääräleima . new ( Timestamped . new ( lähde )) asettaa "Päiväleima ja aikaleima: \n => #{ datestamped_timestamped . write_line } " laittaa ' ' lopun Sisustuskuvio . juosta # => Sisustaja # Lähde: # => Lorem ipsum dolor sit amet # Upcased: # => LOREM IPSUM DOLOR SIT AMET # Aikaleima: # => 18:03 Lorem ipsum dolor sit amet # Päiväysleimaus: # => 03/29/ 19 Lorem ipsum dolor sit amet # Upcased ja aikaleima: # => 18:03 LOREM IPSUM DOLOR SIT AMET # Upcased, päivämääräleima ja aikaleima: # => 03/29/19 18:03 LOREM IPSUM DOLOR SIT AMET # Datestamped: # => 03/29 .19 18:03 Lorem ipsum dolor sit amet

Java

Java esimerkki julkinen käyttöliittymä InterfaceComponent { void doOperation (); } luokka MainComponent toteuttaa InterfaceComponent { @Override public void doOperation () { Järjestelmä . ulos . tulosta ( "Maailma!" ); } } abstrakti luokka Decorator toteuttaa InterfaceComponent { suojattu InterfaceComponent komponentti ; public Decorator ( InterfaceComponent c ) { komponentti = c ; } @Override public void doOperation () { komponentti . doOperation (); } public void newOperation () { Järjestelmä . ulos . println ( "Älä tee mitään" ); } } luokka DecoratorSpace laajentaa Decorator { public DecoratorSpace ( InterfaceComponent c ) { super ( c ); } @Override public void doOperation () { Järjestelmä . ulos . tulostaa ( "" ); super . doOperation (); } @Override public void newOperation () { Järjestelmä . ulos . println ( "Uusi avaruusoperaatio" ); } } luokka DecoratorComma laajentaa sisustaja { public DecoratorComma ( InterfaceComponent c ) { super ( c ); } @Override public void doOperation () { Järjestelmä . ulos . tulostaa ( "," ); super . doOperation (); } @Override public void newOperation () { Järjestelmä . ulos . println ( "Uusi pilkkutoiminto" ); } } luokka SisustajaHei laajentaa sisustaja { public DecoratorHei ( InterfaceComponent c ) { super ( c ); } @Override public void doOperation () { Järjestelmä . ulos . tulosta ( "Hei" ); super . doOperation (); } @Override public void newOperation () { Järjestelmä . ulos . println ( "Uusi hello-operaatio" ); } } luokka pää { public static void main ( Merkkijono ... s ) { Sisustaja c = new DecoratorHei ( new DecoratorComma ( new DecoratorSpace ( new MainComponent ()))); c . doOperation (); // Ohjelman "Hei, maailma!" c . uusiOperaatio (); // Uusi hello-operaatio } }

C#

Esimerkki C#:ssa käyttäen System ; nimitila Decorator { class MainApp { static void Main () { // Luo ConcreteComponent ja kaksi koristelua ConcreteComponent c = new ConcreteComponent (); ConcreteDecoratorA dA = uusi ConcreteDecoratorA (); ConcreteDecoratorB dB = uusi ConcreteDecoratorB (); // Linkkikoristelijat dA . SetComponent ( c ); dB . SetComponent ( dA ); d.A. _ operaatiot (); konsoli . writeLine (); dB . operaatiot (); // Odota käyttäjän konsolia . lue (); } } /// <summary> /// Komponentti - komponentti /// </summary> /// <remarks> /// <li> /// <lu>määritä käyttöliittymä objekteille, jotka voivat olla dynaamisesti /// ylimääräisiä määrätyt vastuut;</lu> /// </li> /// </remarks> abstract class Komponentti { public abstract void Operaatio (); } /// <summary> /// ConcreteComponent - betonikomponentti /// </summary> /// <remarks> /// <li> /// <lu>määrittää objektin, jolla on lisävastuita</lu> / // </li> /// </remarks> class ConcreteComponent : Komponentti { public override void Operation () { Konsoli . kirjoittaa ( "hei" ); } } /// <summary> /// Sisustaja - sisustaja /// </summary> /// <huomautus> /// <li> /// <lu>talloittaa viittauksen objektiin <katso cref="Komponentti" /> ja määrittää rajapinnan /// joka vastaa käyttöliittymää <katso cref="Komponentti"/></lu> /// </li> /// </remarks> abstrakti luokka Decorator : Komponentti { suojattu Komponenttikomponentti ; public void SetComponent ( komponenttikomponentti ) { this . _ komponentti = komponentti ; } julkinen ohitus void Operaatio () { if ( komponentti != null ) { komponentti . operaatiot (); } } } /// <summary> /// ConcreteDecoratorA - betonisuunnittelija /// </summary> /// <huomautus> /// <li> /// <lu>Suorittaa päätehtävän</lu> /// < / li> /// </remarks> class ConcreteDecoratorA : Sisustaja { public override void Operation () { base . operaatiot (); } } /// <summary> /// ConcreteDecorator - betonisuunnittelija /// </summary> /// <remarks> /// <li> /// <lu>Suorittaa päätehtävän + lisätyö</lu> // / </li> /// </remarks> class ConcreteDecoratorB : Sisustaja { public override void Operation () { base . operaatiot (); konsoli . Kirjoita ( "Rauha!" ); } } }

C++

Esimerkki C++:ssa #include <iostream> #sisällytä <muisti> class IComponent { julkinen : virtuaalinen tyhjiötoiminto ( ) = 0 ; virtuaalinen ~ IComponent (){} }; class Komponentti : public IComponent { julkinen : virtuaalinen tyhjä toiminta () { std :: cout << "Maailma!" << std :: endl ; } }; luokka DecoratorOne : julkinen IComponent { std :: jaettu_ptr < IComponent > m_component ; julkinen : DecoratorOne ( std :: jaettu_ptr < IComponent > komponentti ) : m_komponentti ( komponentti ) {} virtuaalinen tyhjä toiminta () { std :: cout << ", " ; m_komponentti -> operaatio (); } }; luokka DecoratorTwo : julkinen IComponent { std :: jaettu_ptr < IComponent > m_component ; julkinen : DecoratorTwo ( std :: jaettu_ptr < IComponent > komponentti ) : m_komponentti ( komponentti ) {} virtuaalinen tyhjä toiminta () { std :: cout << "Hei" ; m_komponentti -> operaatio (); } }; int main () { DecoratorTwo obj ( std :: make_shared < DecoratorOne > ( std :: make_shared < Komponentti > ())); obj . operaatio (); // tulostaa "Hei, maailma!\n" return 0 ; }

D

Esimerkki D-kielellä tuonti std . stdio ; abstrakti luokka Kuva { suojatun merkkijonon nimi ; merkkijono getInfo (); } class Tyhjä : Kuva { ohitusmerkkijono getInfo ( ) { return null ; } } luokka Ympyrä : Kuva { suojattu Kuviokuva ; _ tämä ( kuva f ) { kuva = f ; nimi = "ympyrä" ; } ohittaa merkkijono getInfo () { return name ~ figure . getInfo (); } } luokka Pylväs : Kuva { suojattu Kuviokuva ; _ tämä ( kuva f ) { kuva = f ; nimi = "baari" ; } ohitusmerkkijono getInfo ( ) { return figure . getInfo () ~ nimi ; } } void main () { Kuvaluvut = uusi palkki ( uusi ympyrä ( uusi pylväs ( uusi ympyrä ( uusi Tyhjä ( ))))); writeln ( figures.getInfo ( ) ); }

Python

Alla on esimerkki suunnittelumallin toteutuksesta. Pythonissa on funktion ja luokan sisustajia , joilla on erilainen konsepti kuin suunnittelukuvio.

Python-esimerkki [1] """ Demonstroidut sisustajat maailmassa, jossa on 10x10 arvoruudukko 0-255. """ tuonti satunnaisesti def s32_to_u16 ( x ): jos x < 0 : merkki = 0xf000 else : merkki = 0 alaosa = x & 0x00007ffff palauta alas | merkki def siemen_from_xy ( x , y ): paluu s32_to_u16 ( x ) | ( s32_to_u16 ( y ) << 16 ) luokka RandomSquare : def __init__ ( s , seed_modifier ): s . siemen_muokkaus = siemen_muokkaus def get ( s , x , y ): siemen = siemen_from_xy ( x , y ) ^ s . seed_modifier satunnainen . siemen ( seed ) return satunnainen . randint ( 0 , 255 ) luokka DataSquare : def __init__ ( s , alkuarvo = Ei mitään ): s . data = [ alkuarvo ] * 10 * 10 def get ( s , x , y ): palauttaa s . data [ ( y * 10 ) + x ] # kyllä: nämä ovat kaikki 10x10 def set ( s , x , y , u ): s . data [ ( y * 10 ) + x ] = u luokka CacheDecorator : def __init__ ( s , koristeltu ): s . koristeltu = koristeltu s . välimuisti = DataSquare () def get ( s , x , y ): jos s . välimuisti . get ( x , y ) == Ei mitään : s . välimuisti . asettaa ( x , y , s . koristeltu . saada ( x , y ) ) paluu s . välimuisti . saada ( x , y ) luokka MaxDecorator : def __init__ ( s , koristeltu , max ): s . koristeltu = koristeltu s . max = max def get ( s , x , y ): jos s . koristeltu . saada ( x , y ) > s . max : paluu s . max tuotto s . koristeltu . saada ( x , y ) luokka MinDecorator : def __init__ ( s , koristeltu , min ): s . koristeltu = koristeltu s . min = min def get ( s , x , y ): jos s . koristeltu . saada ( x , y ) < s . min : paluu s . min palautus s . koristeltu . saada ( x , y ) luokka VisibilityDecorator : def __init__ ( s , koristeltu ): s . koristeltu = koristeltu def get ( s , x , y ): palauta s . koristeltu . get ( x , y ) def draw ( s ) : y alueella ( 10 ) : x alueella ( 10 ) : tulosta " % 3d " % s . hanki ( x , y ), tulosta # Rakenna nyt sisustussuunnittelijoiden putki: random_square = RandomSquare ( 635 ) random_cache = CacheDecorator ( satunnainen_neliö ) max_filtered = MaxDecorator ( random_cache , 200 ) min_filtered = MinDecorator ( max_filtered , 100 ) final = VisibilityDecorator ( min_filtered ) lopullinen . piirtää ()

Tulos (huomaa pseudosatunnaislukugeneraattorin käyttö):

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 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 200 129 105 112 100 101 200 200 100 100 100 101 120 180 200 100 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001

PHP

PHP esimerkki abstrakti luokka AbstractComponent { abstrakti julkinen toiminto ( ); } luokka ConcreteComponent laajentaa AbstractComponent { julkisen funktion toiminta () { // ... } } abstrakti luokka AbstractDecorator expands AbstractComponent { suojattu $komponentti ; public function __construct ( AbstractComponent $komponentti ) { $this -> komponentti = $komponentti ; } } class ConcreteDecorator laajentaa AbstractDecorator { julkisen funktion toiminta () { // ... laajennettu toiminnallisuus ... $this -> komponentti -> toiminta (); // ... laajennettu toiminnallisuus ... } } $decoratedComponent = uusi ConcreteDecorator ( uusi ConcreteComponent () ); $decoratedComponent -> operaatio ();

PHP 5

Yleisimmin käytetty PHP5-esimerkki <?php käyttöliittymä IText { julkinen toiminto näyttää (); } class TextHello toteuttaa IText { suojattu $objekti ; public function __construct ( IText $teksti ) { $this -> object = $teksti ; } julkinen toimintoshow () { echo ' Hei' ; $this -> object -> show (); } } class TextWorld toteuttaa IText { suojattu $objekti ; public function __construct ( IText $teksti ) { $this -> object = $teksti ; } julkinen toiminto näytä () { echo 'maailma' ; $this -> object -> show (); } } class TextSpace toteuttaa IText { suojattu $objekti ; public function __construct ( IText $teksti ) { $this -> object = $teksti ; } julkinen toiminto show () { echo ' ' ; $this -> object -> show (); } } luokka TextEmpty toteuttaa ITextin { julkinen funktio näytä () { } } $decorator = uusi TextHello ( uusi TextSpace ( uusi TextWorld ( uusi TextEmpty ()))); $decorator -> show (); // Hello world echo '<br />' . PHP_EOL ; $decorator = uusi TextWorld ( uusi TextSpace ( uusi TextHello ( uusi TextEmpty ()))); $decorator -> show (); // Hei maailma

CoffeeScript

Esimerkki CoffeeScriptistä # Komponenttiluokan Notebook # Markkinointihinta : 500 # $ # Tekniset tiedot hdd: 320 # GB ram: 4 # GB ydin: 'i5 2.3' # GHz # Sisustusluokka NovaNotebook rakentaja : (tuote) -> @hinta = tuote . hinta * 1.3 # Sisustusluokka ImportNotebook rakentaja : (tuote) -> @hinta = tuote . hinta * 1,5 # Sisustusluokan AppleNotebook rakentaja : (tuote) -> @hinta = tuote . hinta * 2.1 macBookInRussia = uusi ImportNotebook uusi NovaNotebook uusi AppleNotebook uusi Notebook - konsoli . loki ( macBookInRussia .price ) _

JavaScript

JavaScript esimerkki

Sisustuskuviota dynaamisesti kirjoitetuilla kielillä voidaan käyttää ilman rajapintoja ja perinteistä OOP-perintöä.

Tämä esimerkki on kopioitu artikkelin englanninkielisestä versiosta. Kahvin hinnan laskeminen:

// ConcreteComponent (luokka koristella myöhemmin) function Kahvi () { this . hinta = funktio () { paluu 1 ; }; } // Decorator A- toiminto Maito ( kahvi ) { this . hinta = funktio () { paluu kahvi . hinta () + 0,5 ; }; } // Sisustus B - toiminto Piiska ( kahvi ) { this . hinta = funktio () { paluu kahvi . hinta () + 0,7 ; }; } // Decorator C -toiminto Sprinkles ( kahvi ) { this . hinta = funktio () { paluu kahvi . hinta () + 0,2 ; }; } // Voidaan käyttää näin: var kahvi = uusi Maito ( uusi Piiska ( uusi Sprinkles ( uusi Kahvi ()))); hälytys ( kahvi.kustannus ( ) ) ; // Tai enemmän visuaalisesti: var coffee = new Coffee (); kahvi = uusi Sprinkles ( kahvi ); kahvi = uusi Piiska ( kahvi ); kahvi = uusi Maito ( kahvi ); hälytys ( kahvi.kustannus ( ) );

Yllä olevan C#-esimerkin toteutus. ConcreteComponentiin on lisätty paikallinen muuttuva hinta, joka muuttuu sekä itsessään että sisustajissa. Luokkien nimet (paitsi jälkiliitteet "A" ja "B") ovat samat kuin mallin jäsenten nimet.

function Komponentti () { tämä . operaatio = funktio () { }; tämä . getPrice = funktio () { }; tämä . setPrice = funktio () { }; } function ConcreteComponent () { var price = 10 ; tämä . operaatio = funktio () { hinta += 4 ; hälytys ( "ConcreteComponent. toiminta, hinta: " + hinta ); }; tämä . getPrice = function ( ) { palautushinta ; }; tämä . setPrice = funktio ( val ) { hinta = val ; }; } ConcreteComponent . prototyyppi = uusi Komponentti (); ConcreteComponent . prototyyppi . konstruktori = ConcreteComponent ; function Sisustaja () { var komponentti ; tämä . setComponent = funktio ( val ) { komponentti = arvo ; }; tämä . getComponent = funktio ( ) { paluukomponentti ; }; tämä . operaatio = funktio () { komponentti . operaatio (); }; tämä . getPrice = function ( ) { paluukomponentti . hanki hinta (); }; tämä . setPrice = function ( val ) { komponentti . setprice ( val ); }; } Sisustaja . prototyyppi = uusi Komponentti (); Sisustaja . prototyyppi . rakentaja = sisustaja ; function ConcreteDecoratorA () { Sisustaja . soita ( tämä ); var toiminta = tämä . toiminta ; // viittaus Decoratorissa määriteltyyn menetelmään tämä . operaatio = funktio () { tämä . setPrice ( tämä . getPrice () + 3 ); hälytys ( "ConcreteDecoratorA. toiminta, hinta: " + tämä . getPrice ()); operaatio (); }; } function ConcreteDecoratorB () { var duplicate = this ; // viittaus instantoituun objektiin (koska tämä voi muuttua) Decorator . soita ( tämä ); var toiminta = tämä . toiminta ; // viittaus Decoratorissa määriteltyyn menetelmään tämä . operaatio = funktio () { tämä . setPrice ( this.getPrice ( ) + 1 ) ; hälytys ( "ConcreteDecoratorB. toiminta, hinta: " + tämä . getPrice ()); lisättyKäyttäytyminen (); operaatio (); }; function addedBehavior () { kaksoiskappale . setPrice ( kaksoiskappale . getPrice ( ) + 2 ); hälytys ( "addedBehavior, hinta: " + kaksoiskappale . getPrice ()); } } // käyttö c = uusi ConcreteComponent (); d1 = uusi ConcreteDecoratorA (); d2 = uusi BetoninkoristelijaB (); hälytys ( "alkuperäinen hinta: " + c . getPrice ()); // kymmenen d1 . setComponent ( c ); d2 . setComponent ( d1 ); d2 . operaatio (); alert ( "hinta muuntamisen jälkeen: " + c . getPrice ()); // kaksikymmentä

VB.NET

Esimerkki: VB.NET Nimitilan sisustaja luokan ohjelma Jaettu alapää () ' Luo ConcreteComponent ja kaksi koristelua Dim C Uutena ConcreteComponentina ( ) Dim D1 Uutena ConcreteDecoratorA ( ) Dim D2 Uutena ConcreteDecoratorinaB ( ) ' Sisustajaviitteet D1 . Aseta komponentti ( C ) D2 . SetComponent ( D1 ) D2 . operaatio () Odotetaan käyttäjäkonsolin toimintoja . Lue () End Sub loppuluokka _ '''' <summary> '''' Komponentti - komponentti ''' </summary> ''' <remarks> ''' <li> ''' <lu>määritä käyttöliittymä objekteille, jotka voidaan määrittää dynaamisesti ''' lisävastuut;</lu> ''' </li> ''' </ remarks > MustInherit Class Component Public MustOverride Sub Operation () Loppuluokka '''' <summary> '''' ConcreteComponent - betonikomponentti ''' </summary> ''' <remarks> ''' <li> ''' <lu>määrittää objektin, jolla on lisävastuita</lu> ' '' </li> '''' </remarks> Luokka ConcreteComponent perii komponentin Julkinen ohittaa alitoiminnot ( ) Konsoli . WriteLine ( "ConcreteComponent.Operation()" ) End Sub End Class '''' <summary> '''' Sisustaja - sisustaja ''' </summary> ''' <huomautukset> ''' <li> ''' <lu> tallentaa viittauksen objektiin <katso cref="komponentti" /> ja määrittää rajapinnan '''', joka vastaa käyttöliittymää <katso cref="komponentti"/></lu> ' '' </li> ''' </remarks> MustInherit Class Decorator perii komponentin suojatun komponentin komponenttina Public Sub SetComponent ( ByVal - komponentti Komponenttina ) Me . komponentti = komponentti End Sub Julkinen ohittaa alitoiminnon ( ) Jos komponentti ei ole mitään , komponentti . Toiminta () End If End Sub End Class '''' <summary> '''' ConcreteDecorator – betonisisustaja ''' </summary> ''' <remarks> ''' <li> ''' <lu>asettaa komponentille lisävastuita.</lu> '' </li> ''' </ remarks > Luokka ConcreteDecoratorA perii sisustaja Yksityinen lisätty Tila merkkijonona Julkinen ohittaa alitoiminnon ( ) MyBase . Operation () addedState = "Uusi tila" -konsoli . WriteLine ( "ConcreteDecoratorA.Operation()" ) End Sub End Class ' "Concrete DecoratorB" Luokka ConcreteDecoratorB perii sisustajan Julkinen ohittaa alitoiminnon ( ) MyBase . Käyttö () LisättyKäyttäytyminen () Konsoli . WriteLine ( "ConcreteDecoratorB.Operation()" ) End Sub Yksityinen Sub AddedBehavior () End Sub End Class End Namespace

Delphi

Delphi- ja Free Pascal -tukiluokkaapulaiset , jotka tekevät koristelukuvion käytöstä tarpeetonta .

Delphi esimerkki ohjelma NoMoreDecorators ; tyyppi TMyObject = luokkamenettely WriteHello ; _ loppu ; TMyObjectHelper = TMyObject - menettelyn luokan apuohjelma WriteHello ( const Nimi : merkkijono ) ; ylikuormitus ; loppu ; menettely TMyObject . Kirjoita Hei ; begin writeln ( 'Hei' ) ; loppu ; menettely TMyObjectHelper . WriteHello ( const Nimi : merkkijono ) ; begin writeln ( 'Hei, ' , Nimi , '!' ) ; loppu ; var o : TMyObject ; begin o := TMyObject . luoda ; o . Kirjoita Hei ; o . WriteHello ( 'farkku' ) ; o . Ilmainen ; loppua . Delphi esimerkki ohjelma DecoratorPattern ; {$APPTYPE CONSOLE} käyttää SysUtilsia ; tyyppi TInterfaceComponent = luokka julkinen menettely Operaatio ; virtuaalinen ; abstrakti ; loppu ; tyyppi TConcreteComponent = luokka ( TInterfaceComponent ) julkinen menettely Operaatio ; ohittaa ; loppu ; menettely TConcreteComponent . toiminta ; begin Write ( 'ei voi' ) ; loppu ; tyyppi TDecorator = luokka ( TInterfaceComponent ) yksityinen FComponent : TInterfaceComponent ; julkinen konstruktori Luo ( aComponent : TInterfaceComponent ) ; loppu ; rakentaja TDecorator . Luo ( aComponent : TInterfaceComponent ) ; begin FComponent := aComponent ; loppu ; tyyppi TBeforeDecorator = luokka ( TDecorator ) julkinen menettely Toiminta ; ohittaa ; loppu ; menettely TBeforeDecorator . toiminta ; begin Write ( 'Suorita,' ) ; FComponent . toiminta ; loppu ; tyyppi TAfterDecorator = luokka ( TDecorator ) julkinen menettely Toiminta ; ohittaa ; loppu ; menettely TAfterDecorator . toiminta ; aloita FComponent . toiminta ; Kirjoita ( 'anteeksi' ) ; loppu ; tyyppi TOverrideDecorator = luokka ( TDecorator ) julkinen menettely Toiminta ; ohittaa ; loppu ; menettely TOverrideDecorator . toiminta ; begin Write ( 'Rakastakaa toisianne!' ) ; loppu ; var vSameComponent : TInterfaceComponent ; begin vSameComponent := TAfterDecorator . Luo ( TConcreteComponent . Create ) ; vSameComponent . toiminta ; // Tulostaa "ei voi anteeksi" Writeln ; vSameComponent := TBeforeDecorator . Luo ( vSameComponent ) ; vSameComponent . toiminta ; // Tulostaa "Execute, can't pardon" Writeln ; vSameComponent := TOverrideDecorator . Luo ( vSameComponent ) ; vSameComponent . toiminta ; // Tulostaa "Rakasta toisianne!" // Yksinkertaisuuden vuoksi esineiden tuhoamista ei näytetä Readln ; loppua .

Swift

Nopea esimerkki protokolla Kirja { var title : String { get set } var price : Int { get set } func getPrice () -> Int } luokka BookImpl : Kirja { var title : String = "" var price : Int = 1000 func getPrice () - > Int { paluuhinta } } luokan alennuskirja : Kirja { let element : BookImpl var title : String = "Groaming-algoritmit" var price : Int = 0 init ( elementti : BookImpl ) { itse . elementti = elementti itse . otsikko = elementti . nimi itse . hinta = elementti . hinta } // 30 % alennus func getPrice () -> Int { paluuhinta - ( hinta * 30 ) / 100 } } // Käytä koristelua anna kirja = BookImpl () anna alennusKirja = AlennusKirja ( elementti : kirja ) tulosta ( alennusKirja . getPrice ())

Kirjallisuus

  • Alan Shalloway, James R. Trott. Suunnittelumalleja. Uusi lähestymistapa olio-suuntautuneeseen suunnitteluun = Design Patterns Explained: A New Perspective on Object-Oriented Design. - M . : "Williams" , 2002. - S. 288. - ISBN 0-201-71594-5 .
  • Eric Freeman, Elizabeth Freeman. Suunnittelukuviot = Head First Design Patterns. - Pietari. : Peter. — 656 s. - ISBN 978-5-459-00435-9 .

Muistiinpanot

  1. Sisustuskuvio . wiki.python.org . Haettu 24. lokakuuta 2021. Arkistoitu alkuperäisestä 24. lokakuuta 2021.

Linkit