Teiesugused lugejad aitavad MUO-d toetada. Kui teete ostu meie saidil olevate linkide abil, võime teenida sidusettevõtte komisjonitasu. Loe rohkem.

Tarkvaraarenduse üks olulisemaid põhimõtteid on avatud-suletud disaini põhimõte. See disainipõhimõte rõhutab, et klassid peaksid olema laiendamiseks avatud, kuid muutmiseks suletud. Dekoraatori kujundusmuster kehastab avatud-suletud disaini põhimõtet.

Dekoraatori kujundusmustri abil saate klassi hõlpsalt laiendada, andes sellele uue käitumise, muutmata selle olemasolevat koodi. Dekoraatori muster teeb seda dünaamiliselt käitusajal, kasutades kompositsiooni. Seda disainimustrit tuntakse paindliku alternatiivina käitumise laiendamiseks pärimise kasutamisele.

Kuidas dekoraatori kujundusmuster töötab?

Kuigi dekoraatori muster on alternatiiv klassi pärand, sisaldab see oma disainis mõningaid pärimise aspekte. Dekoraatori mustri põhiaspektiks on see, et kõik selle klassid on kas otseselt või kaudselt seotud.

Tüüpilisel dekoraatori kujundusmustril on järgmine struktuur:

Ülaltoodud klassiskeemist näete, et dekoraatori mustril on neli peamist klassi.

Komponent: see on abstraktne klass (või liides), mis toimib dekoraatori mustri supertüübina.

Betoonkomponent: need on objektid, mida saate käitusajal erineva käitumisega kaunistada. Nad pärivad komponendi liidesest ja rakendavad selle abstraktseid funktsioone.

Dekoraator: see klass on abstraktne ja sellel on sama supertüüp kui objektil, mida see kaunistab. Klassiskeemil näete kahte seost komponentide ja dekoraatoriklasside vahel. Esimene suhe on pärimissuhe; iga dekoraator on komponent. Teine suhe on kompositsioon; iga dekoraator on (või mähib a) komponenti.

Betooni kaunistaja: need on üksikud dekoraatorid, kes annavad komponendile konkreetse käitumise. Peaksite arvestama, et igal betoonidekoraatoril on eksemplari muutuja, mis sisaldab viidet komponendile.

Dekoraatori kujundusmustri rakendamine Javas

Pitsa tellimise näidisrakendus võib adekvaatselt näidata, kuidas dekoraatori mustrit rakenduste arendamiseks kasutada. See pitsa näidisrakendus võimaldab klientidel tellida pitsasid mitme lisandiga. Dekoraatori mustri esimene klass on pizza liides:

avalikliidesPitsa{
avalikabstraktne String kirjeldus();
avalikabstraktnekahekordnekulu();
}

Pizza liides on komponendiklass. Seega saate sellest luua ühe või mitu konkreetset klassi. Pitsafirma valmistab taigna põhjal kahte peamist tüüpi pitsasid. Ühel pitsatüübil on pärmitainas:

avalikklassYeastCrustPizzarakendabPitsa{
@Alista
avalik String kirjeldus(){
tagasi"Pitsa tainas valmistatud pärmiga";
}

@Alista
avalikkahekordnekulu(){
tagasi18.00;
}
}

YeastCrustPizza on esimene betoon Java klass Pizza liidesest. Teist tüüpi pitsa on saadaval:

avalikklassFlatbreadCrustPizzarakendabPitsa{
@Alista
avalik String kirjeldus(){
tagasi"Pitsa tainas valmistatud lameleivast";
}

@Alista
avalikkahekordnekulu(){
tagasi15.00;
}
}

FlatbreadCrustPizza klass on teine ​​​​betoonkomponent ja sarnaselt YeastCrustPizza klassile rakendab see kõiki Pizza liidese abstraktseid funktsioone.

Dekoraatorid

Dekoraatoriklass on alati abstraktne, nii et te ei saa sellest otse uut eksemplari luua. Kuid on vaja luua suhe erinevate dekoraatorite ja nende kaunistatavate komponentide vahel.

avalikabstraktneklassTopping DekoraatorrakendabPitsa{
avalik String kirjeldus(){
tagasi"Tundmatu kate";
}
}

Klass ToppingDecorator esindab selles näidisrakenduses dekoraatoriklassi. Nüüd saab pitsafirma ToppingDecorator klassi abil luua palju erinevaid katteid (või dekoraatoreid). Oletame, et pitsal võib olla kolme erinevat tüüpi katteid, nimelt juustu, pepperoni ja seeni.

Juustu kate

avalikklassjuustulatubTopping Dekoraator{
privaatne pitsa pitsa;

avalikjuust(Pitsa pitsa){
see.pizza = pitsa;
}

@Alista
avalik String kirjeldus(){
tagasi pizza.description() + ", juustu kate";
}

@Alista
avalikkahekordnekulu(){
tagasipitsa.kulu() + 2.50;
}
}

Pepperoni kate

avalikklassPepperoniulatubTopping Dekoraator{
privaatne pitsa pitsa;

avalikPepperoni(Pitsa pitsa){
see.pizza = pitsa;
}

@Alista
avalik String kirjeldus(){
tagasi pizza.description() + ", Pepperoni topping";
}

@Alista
avalikkahekordnekulu(){
tagasipitsa.kulu() + 3.50;
}
}

Seenekate

avalikklassSeeneulatubTopping Dekoraator{
privaatne pitsa pitsa;

avalikSeene(Pitsa pitsa){
see.pizza = pitsa;
}

@Alista
avalik String kirjeldus(){
tagasi pizza.description() + ", Seenekate";
}

@Alista
avalikkahekordnekulu(){
tagasipitsa.kulu() + 4.50;
}
}

Nüüd on teil lihtne rakendus, mis on rakendatud dekoraatori kujundusmustri abil. Kui klient tellib pärmikoorega pitsa juustu ja pepperoniga, näeb selle stsenaariumi testkood välja järgmine:

avalikklassPeamine{
avalikstaatilinetühinepeamine(String[] args){
Pitsa pitsa1 = uus YeastCrustPizza();
pizza1 = uus Pepperoni (pitsa1);
pizza1 = uus Juust (pitsa1);
System.out.println (pizza1.description() + " $" + pizza1.kulu());
}
}

Selle koodi käivitamine annab konsoolis järgmise väljundi:

Nagu näete, on väljundis kirjas pitsa tüüp koos selle kogumaksumusega. Pitsa sai alguse pärmikoorega pitsa hinnaga 18,00 dollarit, kuid kaunistusmustriga suutis rakendus pitsale lisada uusi funktsioone ja nende sobiva maksumuse. Seega annab pitsale uus käitumine, muutmata olemasolevat koodi (pärmikoorega pitsa).

Dekoraatori mustriga saate ka sama käitumist objektile rakendada nii mitu korda kui soovite. Kui klient tellib pitsa, millel on kõik peal, ja lisaks veidi juustu, saate selle kajastamiseks värskendada põhiklassi järgmise koodiga:

Pitsa pitsa2 = uus YeastCrustPizza();
pizza2 = uus Pepperoni (pitsa2);
pizza2 = uus Juust (pitsa2);
pizza2 = uus Juust (pitsa2);
pizza2 = uus Seene (pitsa2);

System.out.println (pizza2.description() + " $" + pizza2.kulu());

Värskendatud rakendus loob konsoolis järgmise väljundi:

Dekoraatori kujundusmustri kasutamise eelised

Dekoraatori kujundusmustri kasutamise kaks peamist eelist on turvalisus ja paindlikkus. Dekoraatori muster võimaldab teil arendada turvalisemat koodi, mitte sekkudes olemasolevasse turvakoodi. Selle asemel laiendab see olemasolevat koodi kompositsiooni kaudu. Tõhusalt uute vigade või soovimatute kõrvalmõjude sissetoomise vältimine.

Tänu kompositsioonile on arendajal ka palju paindlikkust dekoraatori mustri kasutamisel. Saate igal ajal rakendada uut dekoraatorit, et lisada uus käitumine, ilma olemasolevat koodi muutmata ja rakendust häirimata.