Návrhový vzor strategie (Strategy, Policy) slouží k vyměňování různých implementací algoritmu za běhu programu. Tato záměna může proběhnout buď explicitně (na žádost klienta) nebo implicitně (na základě nastavení ovladače).
Jádrem tohoto vzoru je třída Context, která slouží jako container na jednotlivé postupy. V momentě, kdy dojde k potřebě změny chování, Context prohodí objekty reprezentující dané algoritmy.
Příklad
Mějme pokladnu v baru, pokladna (odpovídá Contextu) umí některé operace, které budou vždy stejné – například vytisknout účtenku, ale zároveň se její chování musí měnit v průběhu času, protože bar pořádá tzv. „Happy hour“, kdy zákazníci mají slevu 10% na jednotlivé nápoje. Z tohoto důvodu je vhodné implementovat chování slev pomocí návrhového vzoru strategie. Tímto se zároveň zajistí snadné přidání dalších akcí do pokladního systému (na vysvědčení pivo pro premianty zdarma atp.).
Kód
01.
/**
02.
* Demostrace navrhoveho vzoru Strategie
03.
* @author Pavel Micka
04.
*/
05.
public
class
StrategyDemonstration {
06.
public
static
void
main(String[] args){
07.
CashDesk c =
new
CashDesk();
08.
c.setStrategy(
new
HappyHourStrategy());
09.
c.add(
20
);
10.
c.add(
80
);
11.
c.printBill();
12.
13.
//Konec Happy Hour
14.
15.
c.setStrategy(
new
NormalStrategy());
16.
c.add(
20
);
17.
c.add(
80
);
18.
c.printBill();
19.
}
20.
}
21.
/**
22.
* Pokladna (Context)
23.
* @author Pavel Micka
24.
*/
25.
class
CashDesk{
26.
/**
27.
* Sem se uklada utrata
28.
*/
29.
private
List<Integer> drinks;
30.
private
BillingStrategy strategy;
31.
32.
public
CashDesk() {
33.
this
.drinks =
new
ArrayList<Integer>();
34.
}
35.
/**
36.
* Prida polozku na ucet
37.
* @param price cena polozky
38.
*/
39.
public
void
add(
int
price){
40.
drinks.add(price);
41.
}
42.
/**
43.
* Vytiskne uctenku
44.
*/
45.
public
void
printBill(){
46.
System.out.println(
"Celkem k zaplaceni: "
+ strategy.sum(drinks));
47.
System.out.println(
"Dekujeme za navstevu, vratte se znovu!"
);
48.
drinks.clear();
49.
}
50.
/**
51.
* Nastavi strategii
52.
* @param strategy strategie
53.
*/
54.
public
void
setStrategy(BillingStrategy strategy) {
55.
this
.strategy = strategy;
56.
}
57.
58.
}
59.
/**
60.
* Uctovaci strategie
61.
* @author Pavel Micka
62.
*/
63.
interface
BillingStrategy{
64.
/**
65.
* Vrati celkovou cenu vypitych napoju
66.
* @return celkova cena
67.
*/
68.
public
double
sum(List<Integer> drinks);
69.
}
70.
/**
71.
* Bezna uctovaci strategie (bezne ceny)
72.
* @author Pavel Micka
73.
*/
74.
class
NormalStrategy
implements
BillingStrategy{
75.
public
double
sum(List<Integer> drinks) {
76.
int
sum =
0
;
77.
for
(Integer i : drinks){
78.
sum += i;
79.
}
80.
return
sum;
81.
}
82.
}
83.
/**
84.
* Strategie pro Happy hour (sleva 10%)
85.
* @author Pavel Micka
86.
*/
87.
class
HappyHourStrategy
implements
BillingStrategy{
88.
public
double
sum(List<Integer> drinks) {
89.
int
sum =
0
;
90.
for
(Integer i : drinks){
91.
sum += i;
92.
}
93.
return
sum*
0.9
;
94.
}
95.
}