Čitatelji poput vas podržavaju MUO. Kada kupite putem poveznica na našoj stranici, možemo zaraditi partnersku proviziju. Čitaj više.

Jedno od najvažnijih načela u razvoju softvera je načelo dizajna otvoreno-zatvoreno. Ovo načelo dizajna naglašava da klase trebaju biti otvorene za proširenje, ali zatvorene za izmjene. Uzorak dizajna dekoratera utjelovljuje načelo dizajna otvoreno-zatvoreno.

S uzorkom dizajna dekoratera možete jednostavno proširiti klasu dajući joj novo ponašanje bez mijenjanja postojećeg koda. Uzorak dekoratera to radi dinamički tijekom izvođenja, koristeći kompoziciju. Ovaj obrazac dizajna poznat je kao fleksibilna alternativa korištenju nasljeđivanja za proširenje ponašanja.

Kako funkcionira uzorak dizajna dekoratera?

Iako je ukrasni uzorak alternativa klasno nasljeđe, u svoj dizajn uključuje neke aspekte nasljeđivanja. Ključni aspekt obrasca dekoratera je da su sve njegove klase povezane, bilo izravno ili neizravno.

Tipični dizajn dekoraterskog uzorka ima sljedeću strukturu:

instagram viewer

Iz gornjeg dijagrama klasa možete vidjeti da uzorak dekoratera ima četiri glavne klase.

komponenta: ovo je apstraktna klasa (ili sučelje), koja služi kao supertip za uzorak dekoratera.

Komponenta betona: ovo su objekti koje možete ukrasiti različitim ponašanjem tijekom izvođenja. Oni nasljeđuju sučelje komponente i implementiraju njegove apstraktne funkcije.

Dekorater: ova klasa je apstraktna i ima isti supertip kao i objekt koji će ukrasiti. U dijagramu klasa vidjet ćete dva odnosa između klasa komponente i dekoratora. Prvi odnos je odnos nasljeđivanja; svaki dekorater je komponenta. Drugi odnos je odnos sastava; svaki dekorater ima (ili obavija) komponentu.

Dekorater betona: to su pojedinačni dekoratori koji komponenti daju specifično ponašanje. Trebate imati na umu da svaki betonski dekorater ima varijablu instance koja sadrži referencu na komponentu.

Implementacija obrasca dizajna Decorator u Javi

Uzorak aplikacije za naručivanje pizze može primjereno demonstrirati kako koristiti uzorak dekoratera za razvoj aplikacija. Ova aplikacija za uzorke pizze kupcima omogućuje naručivanje pizza s višestrukim dodacima. Prva klasa obrasca dekoratera je sučelje pizze:

javnostsučeljePizza{
javnostsažetak Niz opis();
javnostsažetakdvostrukotrošak();
}

Pizza sučelje je klasa komponente. Dakle, iz njega možete stvoriti jednu ili više konkretnih klasa. Pizza tvrtka proizvodi dvije glavne vrste pizza, na temelju njihova tijesta. Jedna vrsta pizze ima tijesto od kvasca:

javnostrazredaPizza s korom od kvascaoruđaPizza{
@Nadjačaj
javnost Niz opis(){
povratak"Tijesto za pizzu s kvascem";
}

@Nadjačaj
javnostdvostrukotrošak(){
povratak18.00;
}
}

YeastCrustPizza je prvi beton Java klasa sučelja Pizza. Druga dostupna vrsta pizze je somun:

javnostrazredaFlatbreadCrustPizzaoruđaPizza{
@Nadjačaj
javnost Niz opis(){
povratak"Tijesto za pizzu od somuna";
}

@Nadjačaj
javnostdvostrukotrošak(){
povratak15.00;
}
}

Klasa FlatbreadCrustPizza druga je konkretna komponenta i, poput klase YeastCrustPizza, implementira sve apstraktne funkcije sučelja Pizza.

Dekorateri

Klasa dekoratera je uvijek apstraktna, tako da ne možete stvoriti novu instancu izravno iz nje. Ali potrebno je uspostaviti odnos između različitih dekoratera i komponenti koje će dekorirati.

javnostsažetakrazredaToppingDecoratororuđaPizza{
javnost Niz opis(){
povratak"Nepoznati preljev";
}
}

Klasa ToppingDecorator predstavlja klasu dekoratera u ovom uzorku aplikacije. Sada tvrtka koja se bavi proizvodnjom pizze može stvoriti mnogo različitih nadjeva (ili dekoratora), koristeći klasu ToppingDecorator. Recimo da pizza može imati tri različite vrste nadjeva, naime sir, feferoni i gljive.

Preljev od sira

javnostrazredaSirproteže seToppingDecorator{
privatna Pizza pizza;

javnostSir(pizza pizza){
ovaj.pizza = pizza;
}

@Nadjačaj
javnost Niz opis(){
povratak pizza.description() + ", preljev od sira";
}

@Nadjačaj
javnostdvostrukotrošak(){
povratakpizza.trošak() + 2.50;
}
}

Preljev od feferona

javnostrazredaFeferoniproteže seToppingDecorator{
privatna Pizza pizza;

javnostFeferoni(pizza pizza){
ovaj.pizza = pizza;
}

@Nadjačaj
javnost Niz opis(){
povratak pizza.description() + ", preljev od feferona";
}

@Nadjačaj
javnostdvostrukotrošak(){
povratakpizza.trošak() + 3.50;
}
}

Preljev od gljiva

javnostrazredaGljivaproteže seToppingDecorator{
privatna Pizza pizza;

javnostGljiva(pizza pizza){
ovaj.pizza = pizza;
}

@Nadjačaj
javnost Niz opis(){
povratak pizza.description() + ", preljev od gljiva";
}

@Nadjačaj
javnostdvostrukotrošak(){
povratakpizza.trošak() + 4.50;
}
}

Sada imate jednostavnu aplikaciju implementiranu pomoću obrasca dizajna dekoratera. Ako kupac naruči pizzu s kvascem sa sirom i feferonima, testni kod za taj scenarij izgledat će ovako:

javnostrazredaGlavni{
javnoststatičkiponištitiglavni(String[] argumenti){
Pizza pizza1 = novi Kora od kvascaPizza();
pizza1 = novi Feferoni (pizza1);
pizza1 = novi Sir (pizza1);
System.out.println (pizza1.description() + " $" + pizza1.cost());
}
}

Pokretanje ovog koda proizvest će sljedeći izlaz u konzoli:

Kao što vidite, rezultat navodi vrstu pizze zajedno s njezinom ukupnom cijenom. Pizza je počela kao pizza s korom od kvasca za 18,00 USD, ali s uzorkom dekoratera aplikacija je pizzi mogla dodati nove značajke i njihovu odgovarajuću cijenu. Dakle, dajući pizzi novo ponašanje bez mijenjanja postojećeg koda (pizza s korom od kvasca).

S uzorkom dekoratera također možete primijeniti isto ponašanje na objekt onoliko puta koliko želite. Ako kupac naruči pizzu sa svime što je na njoj, i malo dodatnog sira, možete ažurirati glavnu klasu sa sljedećim kodom koji to odražava:

Pizza pizza2 = novi Kora od kvascaPizza();
pizza2 = novi Feferoni (pizza2);
pizza2 = novi Sir (pizza2);
pizza2 = novi Sir (pizza2);
pizza2 = novi Gljive (pizza2);

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

Ažurirana aplikacija proizvest će sljedeći izlaz u konzoli:

Prednosti korištenja obrasca dizajna dekoratera

Dvije glavne prednosti korištenja obrasca dizajna dekoratera su sigurnost i fleksibilnost. Uzorak dekoratora omogućuje vam razvoj sigurnijeg koda ne ometajući već postojeći sigurni kod. Umjesto toga proširuje postojeći kod kroz kompoziciju. Učinkovito sprječava uvođenje novih grešaka ili neželjenih nuspojava.

Zbog sastava razvijač također ima veliku fleksibilnost pri korištenju uzorka dekoratora. Možete implementirati novi dekorater u bilo kojem trenutku kako biste dodali novo ponašanje, bez mijenjanja postojećeg koda i ometanja aplikacije.