T 3.8 design paterni (c)
-
Upload
zoran-jeremic -
Category
Education
-
view
322 -
download
9
Transcript of T 3.8 design paterni (c)
DECORATORStrukturni paterni
2
Opis problema
Kao jedan od vodećih svetskih lanaca sa coffee shop konceptom, Costa Coffee u proseku otvara po pet kafeterija nedeljno, na različitim lokacijama širom sveta.
Zbog tako velikog rasta, neprekidno se trude da obogate svoju ponudu novim napicima.
3
4
Opis problema
Osim kafe, moguće je naručiti i priloge, kao što su šlag, mleko, soja, čokolada, i svi oni utiču na cenu, pa ih je potrebno ugraditi u sistem.
5
Opis problema
Očigledno je dati model komplikovan i težak za održavanje. Šta se dešava kada cena mleka skoči? Šta se deš
Možemo li osnovnoj klasi Beverage dodati promenjlive koje pokazuju da li napitak ima neki dodatak?
6
Opis problema
7
Implementacija klasa
Ovakav model značajno smanjuje broj klasa, ali određeni problemi i dalje nisu rešeni. Šta se dešava u slučaju budućih promena (promena cene, novi
prilozi, novi napici)?
8
public class Beverage {double cost() {
//izracunati cenu sa dodacima
}
public class DarkRoast extendsBeverage {
public DarkRoast(){description=“Most Excellent Dark
Roast”;}
double cost() {super.coast();//izracunati cenu tipa kafe
}
Decorator
Namena Dinamički dodeljuje dodatnu odgovornost objektima. Decorator
obezbeđuje fleksibilnu alternativu proširivanju podklasa zbog proširivanja funkcionalnosti.
Problem Želite da dodate ponašanje ili stanje pojedinačnim objektima u
vreme izvršenja. Nasleđivanje nije moguće jer je statičko i primenjuje se na čitavu klasu.
9
Primena na opisani problem
Pretpostavimo da kupac želi DarkRoast sa čokoladom (Mocha) i šlagom (Whip)
Uzmite DarkRoast objekat
Dekorišite ga Mocha objektom
Dekorišite ga Whip objektom
Pozovite cost() metodu i koristite delegiranje da bi dodali troškove priloga.
10
Primena na opisani problem
Započinjemo sa DarkRoast objektom
Kupac je tražio Mocha, tako da kreiramo Mocha objekat tako da obuhvata DarkRoast.
11
Primena na opisani problem
Kupac takođe želi šlag (Whip), pa kreiramo Whip dekorator i smeštamo Mocha unutar njega.
12
Izračunavanje cene
13
Decorator – dijagram klasa
14
Dijagram klasa kafeterije
15
Implementacija klasa Beverage i CondimentDecorator
16
public abstract class Beverage {String description=“Unknown Beverage”;
public String getDescription(){return description;
}public abstract double cost();
}
public abstract class CondimentDecorator extends Beverage {public abstract String getDescription();
}
Implementacija konkretnih komponenti
17
public class Espresso extends Beverage {
public Espresso(){description=“Espresso”;
}public double cost(){
return 1.99;}
}
public class HouseBlend extends Beverage {
public Espresso(){description=“House Blend Coffe”;
}public double cost(){
return 0.89;}
}
Implementacija konkretnih dekoratora
18
public class Mocha extends CondimentDecorator {Beverage beverage;
public Mocha(Beverage beverage){this.beverage=beverage;
}public String getDescription(){
return beverage.getDescription() + “, Mocha”;}public abstract double cost(){
return 0.20 + beverage.cost();}
}
Korišćenje dekoratora
19
public class StarbuzzCoffee {public static void main(String args[]) {
Beverage beverage = new Espresso();System.out.println(beverage.getDescription()+ “ $” + beverage.cost());
Beverage beverage2 = new DarkRoast();beverage2 = new Mocha(beverage2);beverage2 = new Mocha(beverage2);beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription()+ “ $” + beverage2.cost());
Beverage beverage3 = new HouseBlend();beverage3 = new Soy(beverage3);beverage3 = new Mocha(beverage3);beverage3 = new Whip(beverage3);System.out.println(beverage3.getDescription()+ “ $” + beverage3.cost());
}}
Decorator - Primenljivost
Za dodavanje odgovornosti pojedinačnim objektima na dinamički i transparentan način, tj. bez uticaja na druge objekte,
Za odgovornosti koje mogu da se povuku,
Kada proširenje pomoću pravljenja podklasa nije praktično.
20
Decorator - posledice
Prednosti: Veća fleksibilnost od staičkog nasleđivanja, Izbegavaju se klase prebogate karakteristikama visoko u
hijerarhiji.
Nedostaci: Dekorator i njegova komponenta nisu identični. Dekorator služi
kao transparentni omotač, pa prema tome ne bi trebalod a se oslanjate na identitet objekta kada koristite dekoratere.
Mnogo malih objekata. Ako se u projektu mnogo koristi Decorator, dobiće se sistem sastavljen od mnogo sličnih malih objekata. Objekti se razlikuju samo po tome kako su međusobno povezani, a ne prema klasi ili vrednostima promenljivih. U takvom sistemu teško je analizirati greške.
21
FACTORYPaterni kreiranja
22
Opis problema
Kada koristimo new mi zapravo instanciramo konkretnu klasu, tako da je to definitivno implementacija a ne interfejs.
Kada imamo skup povezanih konkretnih klasa, često pišemo kod poput ovog:
23
Duck duck = new MallardDuck();
Duck duck;
If (picnic) {duck = new MallardDuck();
} else if (hunting) {duck = new DecoyDuck();
}else if (inBathTub){duck = new RubberDuck();
}
Opis problema
Kod pisan kroz interfejse će raditi kroz polimorfizam sa bilo kojom novom klasom koja implementira interfejs.
Međutim kada imamo dostra konkretnih klasa, kod se mora menjati dodavanjem novih konkretnih klasa.
24
Opis problema
25
Pizza orderPizza(){Pizza pizza = new Pizza ();
pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;
}
Zbog fleksibilnostiPizza je abstraktna
klasa
Opis problema
26
Pizza orderPizza(String type){Pizza pizza = new Pizza ();
pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;
}
if (type.equals(“cheese”)) {pizza = new CheesePizza();
} else if (type.equals(“greek”) {pizza = new GreekPizza();
} else if (type.equals(“pepperoni”) {pizza = new PepperoniPizza();
}
Sada prosleđujemo vrstu pice kao
argument
Na osnovu vrste pice instanciramo
konkretnu klasu i dodeljujemo je
promenljivoj pizza
Opis problema
27
Pizza orderPizza(String type){Pizza pizza = new Pizza ();if (type.equals(“cheese”)) {
pizza = new CheesePizza();} else if (type.equals(“greek”) {
pizza = new GreekPizza();} else if (type.equals(“pepperoni”) {
pizza = new PepperoniPizza();
pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;
}
Kod se morakonstantno menjati u skladu sa ponudama
picerije
} else if (type.equals(“clam”)) {pizza = new ClamPizza();
} else if (type.equals(“veggie”) {pizza = new VeggiePizza();
}
Enkapsulacija kreiranja objekta
28
Pizza orderPizza(String type){Pizza pizza = new Pizza ();
pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;
}
if (type.equals(“cheese”)) {pizza = new CheesePizza();
} else if (type.equals(“pepperoni”) {pizza = new PepperoniPizza();
} else if (type.equals(“clam”)) {pizza = new ClamPizza();
} else if (type.equals(“veggie”) {pizza = new VeggiePizza();
}
Jednostavan pizza factory
29
public class SimplePizzaFactory {
public Pizza createPizza(String type) {Pizza pizza = null;if (type.equals(“cheese”)) {
pizza = new CheesePizza();} else if (type.equals(“pepperoni”)) {
pizza = new PepperoniPizza();} else if (type.equals(“clam”)) {
pizza = new ClamPizza();} else if (type.equals(“veggie”)) {
pizza = new VeggiePizza();}return pizza;
}}
Metodu createPizza() koriste svi klijenti zainstanciranje novih
objekata.
Ovaj kod je još uvek parametrizovan
vrstom pice, kao i u originalnoj
orderPizza() metodi.
PizzaStore klasa
30
public class PizzaStore {
public Pizza orderPizza(String type) {Pizza pizza;
pizza.prepare();pizza.bake();pizza.cut();
pizza.box();return pizza;
}// other methods here}
SimplePizzaFactory factory;public PizzaStore(SimplePizzaFactory factory) {this.factory = factory;}
pizza = factory.createPizza(type);
PizzaStore klasi se prosleđuje factory kroz
konstruktor
orderPizza() metoda koristi factory da kreira
picu jednostavnim prosleđivanjem tipa pice
Dijagram klasa
31