parsisiųsti skaidrę

Download Report

Transcript parsisiųsti skaidrę

Decorator
(Structural)
Decorator
 Šablonas leidžia dinamiškai (programos
vykdymo metu) dekoruoti jau egzistuojančio
objekto elgseną.
 Dekoruoti – panaudoti objekto gautus
rezultatus tolesniam jų apdorojimui kitais
skaičiavimais.
 Lanksti ir dinaminė alternatyva statiniam
paveldimumo taikymui.
2
Realaus pasaulio pavyzdys
3
Motyvacija
 Naudojant Decorator šabloną, išplečiamos ne
klasės, o tik atskiro jos egzemplioriaus
funkcionalumas.
 Vien
paveldimumu tokio rezultato
pasiekti neįmanoma.
 Šablonas leidžia išplėsti atskiro
egzemplioriaus funkcionalumą,
nemodifikuojant kitų jo klasės
egzempliorių.
4
Motyvacija
 Dekoratoriaus (Wrapper) interfeisas yra toks pats,
kaip dekoruojamo objekto interfeisas.
 Visi pranešimai, siunčiami pirminiam objektui, eina
per jį dekoruojančius dekoratorius.
 Dekoratorius gali papildyti dekoruojamo objekto
funkcionalumą prieš pasiunčiant jam pranešimą arba
po to.
 Dekoratorius galima keisti dinamiškai.
 Objekto modifikavimas per paveldimumą yra
statinis ir atitinkama klasių hierarchija turi būti
žinoma iš anksto.
5
Motyvacija
 Naudojant dekoratorius, galima išvengti
perteklinio klasių skaičiaus programoje.
 Jei reikia praplėsti pirminio objekto
funkcionalumą keliolika būdų naudojant
paveldėjimą, gausis labai didelis klasių skaičius.
 Paveldėjimo atveju visoms galimoms
funkcionalumo kombinacijoms turime kurti
atitinkamą klasę.
 Dekoravimo atveju klases kuriame tik atskiroms
funkcionalumo dalims.
6
Motyvacija
 Kadangi dekoratoriaus interfeisas yra
suderintas su jo dekoruojamo objekto
interfeisu, kreipiniai į šiuos abu objektus yra
identiški.
 Tai leidžia lanksčiai, bet kokia tvarka
komponuoti dekoratorių objektus ir taip gauti
praktiškai neribojamas pirminio objekto
funkcionalumo modifikavimo galimybes.
7
Klasių diagrama
8
Struktūra
 Component – abstrakti klasė (arba interfeisas),
nustatanti minimalų dekoratorių ir dekoruojamų
objektų bendravimo interfeisą.
 Tai tą pačią antraštę turintys dekoratorių ir
dekoruojamų objektų metodai, kurių varde yra
žodis operation.
 Abstrakčią klasę Component turi išplėsti ir
dekoruojamo (pirminio) objekto klasė
ConcreteComponent, ir dekoratorių klasių
hierarchijos bazinė klasė Decorator.
 Per bendrą interfeisą galima vienu būdu apdoroti ir
konkrečius komponentus, ir dekoratorius, sujungiant
juos i grandinę.
9
Struktūra
 Klasė Decorator turi nuorodą component į
abstrakčią klasę (interfeisą) Component, per
kurią galima pasiekti dekoruojamos klasės
egzempliorius.
 Kūrimo metu nurodyta seka kiekvienas
konkretus dekoratorius priskiria nuorodą
component į toliau sekoje einantį konkretų
dekoratorių.
 Savo ruožtu į jį patį įgyja nuorodą prieš jį
einantis sekoje konkretus dekoratorius.
10
Struktūra
 Dekoratorių klasių hierarchijoje užklojamas
klasės Component metodas operation.
 Konkretūs dekoratoriai per nuorodą
component gali pasiekti vieni kitus bei
konkretų komponentą ir taip keisti jo
funkcionalumą (panaudoti jo rezultatus savo
skaičiavimams).
 Papildomą konkrečių dekoratorių
funkcionalumą diagramoje vaizduoja metodai
AddedBehavior.
11
Pavyzdys
12
Pavyzdžio objektų ir klasių
diagrama
13
Pavyzdys Nr.2
 Vertically scrolling 2D space shooters have a spaceship
that:


Banks left or right, depending on motion
Typically have three animations:

Banking left, straight ahead, banking right
 Also want to

Add particle effect for exhaust if the ship is
moving up the screen


But turn this off if it’s moving down the screen
Add a shield in front of the ship if the player picks up a shield
powerup.
 Could accomplish all of these visuals using a series of
combined animations


Bank left, bank left and shield, bank left and
exhaust, bank left and shield and exhaust, etc..
But, leads to combinatoric expansion.
14
Decorating the spaceship with shield & exhaust
 Instead of pre-defining all possible
animations…
 Draw the shield, exhaust, and spaceship
separately


Can think of “decorating” the spaceship with a
shield, or an exhaust particle effect, as needed
No longer need large combinations of
animations
15
Some powerup options in Gradius
Gratuitous picture of a Vic Viper model
Decorators using object-oriented code
 Basic idea is to create a linked list of objects

Each object draws one part of final scene…



E.g., the exhaust, the shield, etc.
… then calls the next object on the list
The final object is the main object being decorated

E.g., the spaceship
exhaust
shield
shield
spaceship
Exhaust, shield, and spaceship are object instances
spaceship
16
Realizacijos detalės
 May need to know details about terminal object
 Need to know position of spaceship to put shield directly in front,
and exhaust directly in back
 Each object in list can be given reference to terminal object

Use reference to spaceship object to retrieve its current location
 May need to remove a decorator
 E.g., shields no longer active
 Will need to write code that removes a decorator instance, and
repairs the links among remaining ones
 If the removed decorator is the first in the chain, removal is easy
17
Pasekmės (+)
 Didesnis lankstumas nei paveldėjimo atveju.
Su dekoratoriais atsakomybės gali būti pridėtos ar pašalintos
vykdymo metu.
 Paveldėjimas reikalauja sukurti naują klasę, kiekvienai
naujai atsakomybei (pvz. BorderedScrollableTextView,
BorderedTextView). Tai padidina sistemos sudėtingumą.
 Su dekoratoriais lengva pridėti tą pačią savybe kelis kartus (pvz.
dvigubas rėmelis).
 Išvengiama įvairiomis savybėmis perkrautų klasių.
 Galima apsibrėžti paprastą klasę ir papildyti jos
funkcionalumą dekoratorių pagalba.
 Funkcionalumas gali būti sukomponuotas iš paprastų dalių.
 To pasekoje taikomajai programai nereikia „mokėti“ už
savybes, kurių ji nenaudoja.

18
Pasekmės (-)
 Dekoratorius ir jo komponentas nėra identiški.

Reikalingas sudėtingesnis situacijos
valdymas, kuomet reikia tiesioginio priėjimo
prie galutinio komponento.
 Daug mažų objektų.



Naudojant šabloną, galutinė sistema dažnai
susideda iš didelio kiekio mažų objektų, kurie
yra panašūs.
Objektai skiriasi tik tuo, kaip jie yra sujungti, o
ne savo klasėmis ar kintamųjų reikšmėmis.
Tokias sistemas sunku derinti ir perprasti.
19
Pavyzdys Nr.3
 Konkretus komponentas gali pakelti skaičių
kvadratu.
 Dekoratoriai suteikia dvi papildomas
galimybes:


Padauginti konkretaus komponento gautą
rezultatą iš trijų;
Rasti jo natūrinį logaritmą.
20
Realizacija
Nuoroda, per kurią
dekoratoriai gali pasiekti ir
dekoruojamos klasės
ConcreteComponent
egzempliorius ir vieni kitus.
21
Rezultatas
component = CD1(CD1(CD2(component)
result*result
22
Rezultatas
 Pagal šabloną dekoravus komponentą ,
klientui pakanka naudotis tik abstrakčiuoju
duomenų tipu (Component) ir taip išvengti
priklausomybės nuo konkrečių komponentų ir
dekoratorių klasių.
23
Command
(Behavioral)
24
Command
 Šablonas siūlo komandoms ar jų grupėms
sukurti atitinkamą objektą.
 Pasitelkiant šį objektą, komandas galima
saugoti, perduoti per parametrus, grąžinti
kaip ir bet kokį kitą objektą bei palaikyti
atšaukimo (undo) komandų seką.
25
Realaus pasaulio pavyzdys
26
Command kaip Macro
 „Objektas, turintis simbolį, vardą ar raktą, kuris
reiškia komandų sąrašą, veiksmus ar klavišo
paspaudimus“.
 Macro atvaizduoja komandą, kuri yra sudaryta iš
aibės apjungtų kitų komandų, nustatyta tvarka.
 Command šablonas uždaro (encapsulates)
komandas (method calls) objektuose, tokiu būdu
leisdamas paskelbti užklausas nežinant
pageidaujamos operacijos ar objekto.
 Šablonas suteikia galimybę sudaryti komandų eiles,
undo/redo veiksmus ir kitas manipuliacijas.
27
Motyvacija
 Vartotojui sąveikaujant su taikymu, jo komandų
apdorojimo logika gali būti labai sudėtinga.
 Bandymas numatyti visus galimus vartotojo
veiksmus ir sukurti tinkamai juos sąlygos sakiniais
interpretuojantį kodą gali būti ne tik
neįgyvendinamas, bet ir beprasmis.
 Tokį kodą sunku modifikuoti keičiant vartotojo ir
taikymo sąveikos taisykles ar papildant jų sąveiką
naujomis komandomis.
 Situacija taptų dar komplikuotesnė, jei
numatytume galimybę vartotojui atšaukti savo
veiksmus ar sujungti juos i makrokomandas.
28
Motyvacija
 Norint gana lanksčiai manipuliuoti komandomis,
reikia jas „paversti“ objektais.
 „Komandų objektų“ atvejis pasižymi tam tikra
specifika:
 Iš anksto nėra žinoma, kokia komanda ir kokiam
objektui bus pateikta vienu ar kitu metu.
 Šablonas suteikia galimybę dinamiškai parinkti
kiekvienai komandai reikiamą operaciją ir ją
atliekantį objektą.
 Išsprendžiama dažna problema – atskiriami
pranešimo sukūrimo ir jo apdorojimo procesai.
29
Klasių diagrama
30
Struktūra
 Command šablonas numatomoms operacijoms atlikti
naudoja Command (komandų) klasių hierarchiją.
 Jos viršuje yra abstrakti klasė (interfeisas)
Command.
 Ji turi abstraktų metodą execute.


Tai dinamiškai vykdomas komandų hierarchijos
metodas, kurį iškviečia klasės Invoker
egzempliorius (iškviečia komandą).
Šis metodas numatytiems komandos veiksmams
atlikti kreipiasi į klasės Receiver egzemliorių.
31
Struktūra
 Klasė Receiver aprašo objektą, kurio
būseną keičia komandos.
 Abstrakčią klasę Command išplečia klasės
ConcreteCommand.


Komandų hierarchijos egzemlioriai vadinami
konkrečiomis komandomis.
Kiekviena iš ConcreteCommand klasių turi
individualų metodo execute turinį, kuriame
aprašoma, kokie klasės Receiver metodai
yra iškviečiami konkrečioje komandoje.
32
Struktūra
 Charakteringas šablono požymis – kliento klasėje sukuriami
ConcreteCommand egzemplioriai, kuriuos jis inicijuoja
atitinkamais klasės Receiver egzemlioriais.
 Naudojant tokį jungtinį objektą – klasės ConcreteCommand
egzemliorių, gerokai supaprastėja komandų apdorojimo logika.
 execute yra polimorfinis (užklojantysis) metodas, todėl visos
komandos traktuojamos vienodai.

Tai leidžia nesunkiai papildyti/pakeisti jų sąrašą.
 Konkretų vykdomo metodo execute turinį sudaro iškviečiamos
klasės Receiver metodai.
 Invoker egzemplioriuje gali būti iš anksto nežinoma nei kokia
konkreti operacija, nei su kokiu objektu ji bus atlikta.

Pranešimą galima parinkti, išsiųsti ir įvykdyti nepriklausomais laiko
momentais.
33
Sekų diagrama (1)
34
Sekų diagrama (2)
 Klientas sukuria ConcreteComand objektą ir
specifikuoja juo gavėją (receiver).
 Invoker objektas saugo ConcreteCommand.
 Iškvietėjas (invoker) paleidžia užklausą
iškviesdamas Execute komandai.


Kuomet komandas galima anuliuoti (undo),
ConcreteCommand laiko būseną, esančią
prieš Execute iškvietimą.
ConcereteCommand objektas iškviečia
operacijas, užklausos apdorojimui.
35
Kada naudoti Command šabloną?
 Reikalinga užklausų istorija.
 Reikalingas undo (callback) funkcionalumas.
 Užklausos turi būti apdorojamos skirtingais
laiko momentais ir skirtinga tvarka.
 Iškvietėjas turi būti atskirtas nuo objekto,
apdorojančio iškvietimą.
36
Klasių diagrama
37
Pavyzdys
 Padavėjas (Invoker) priima užsakymą iš kliento. Užsakymas
statomas į eilę ir patenka pas virėją, kur yra apdorojamas.
38
Dalyviai pavyzdyje
 Client yra klientas:
Siunčia užklausą gavėjui (receiver) per padavėją
(Invoker).
 Padavėjas uždaro (encapsulates) komandą
(užsakymą) užrašydamas ją ant čekio ir pateikia
virtuvei (sukuriamas ConcreteComand objektas,
kuris ir yra komanda).
 Virėjas (Receiver), pabaigęs gaminti kitus
užsakymus, kurie jam buvo nusiusti prieš tai, pradeda
apdoroti gautą užsakymą.

39
Pasekmės
 Šablonas atskiria objektą, kuris iškviečia
operaciją, nuo to objekto, kuris žino kaip ją
vykdyti.
 Komandos yra pirminės klasės (first class)
objektai. Jomis galima manipuliuoti ir jas
praplėsti kaip bet kurį kitą objektą.
 Galima sujungti komandas į vieną jungtinę
komandą.
 Lengva pridėti naujas komandas, kadangi
nereikia keisti egzistuojančių klasių.
40
Pavyzdys
 Receiver egzemlioriaus simbilių eilutės
kintamasis gali būti modifikuojamas dviem
komandomis:


Tarpų tarp žodžių pakeitimas žvaigždutėmis;
Mažųjų raidžių pakeitimas didžiosiomis.
41
Realizacija
42
Realizacija
 Testo metu keliems klasės Receiver
egzemplioriams klientas sukuria kelias
konkrečias komandas jų būsenai modifikuoti.
 Iškviečiant konkrečioms komandoms polimorfinį
metodą execute parodoma, kad Invoker
egzemlioriaus komandoms apdoroti galima
atsisakyti tradicines sąlygos sakinių logikos:

Bus vykdomas tos konkrečios komandos metodas
execute , kuriai tuo metu bus priskirta kliento
Command tipo nuoroda.
43
Rezultatas
 Šablono pagalba galima sukurti konkrečias
komandas, manipuliuoti jomis kaip paprastais
objektais ir jas vykdyti naudojant tik komandų
hierarchijos interfeisą Command.
 Atskyrę Invoker nuo jo naudojamų konkrečių
komandų klasių, sudarome prielaidas kurti aiškesnį,
lengvai plečiamą ir vystomą, komandų apdorojimui
skirtą kodą.
44
Pabaiga
45