You are on page 1of 58

Id do

Spis treci
Przykadowy rozdzia
Katalog ksiek
Katalog online
Zamw drukowany
katalog
Twj koszyk
Dodaj do koszyka
Cennik i informacje
Zamw informacje
o nowociach
Zamw cennik
Czytelnia
Fragmenty ksiek
online

Kontakt
Helion SA
ul. Kociuszki 1c
44-100 Gliwice
tel. 32 230 98 63
e-mail: helion@helion.pl
Helion 19912010

Wzorce projektowe.
Rusz gow!
Autorzy: Elisabeth Freeman, Eric Freeman,
Bert Bates, Kathy Sierra
Tumaczenie: Adam Balcerzak, Marcin Jdrysiak,
Tomasz Wasilewski
ISBN: 978-83-246-2803-2
Tytu oryginau: Head First Design Patterns
Format: 200230, stron: 656

Otwrz swj umys. Poznaj wszystko, co zwizane z wzorcami projektowymi, w sposb


gwarantujcy szybkie i skuteczne opanowanie zasad ich stosowania. Zapomnij o listingach
liczcych tysice wierszy, dugich i nucych opisach teoretycznych oraz rozbudowanych
schematach zalenoci. Wzorce projektowe to gotowe opisy rozwiza najczstszych
problemw napotykanych przy tworzeniu oprogramowania. Aby je prawidowo stosowa,
naley pozna zaoenia, na podstawie ktrych zostay stworzone, oraz nauczy si
implementowa je we waciwy sposb.
Naprzd, gowo!
Nikt ci tego nie potrafi wytumaczy? Wydaje Ci si, e to problem nie na Twoj gow?
Nie potrzebujesz elektrowstrzsw, eby pobudzi swj mzg do aktywnego dziaania.
Tylko adnych gwatownych gestw! Usid wygodnie, otwrz ksik, dopiero teraz
si zacznie. Na pocztek rusz gow!
Precz z nudnymi wykadami i zakuwaniem bez zrozumienia!
Nauka to znacznie wicej ni tylko czytanie suchego tekstu. Twj mzg jest niczym
godny rekin, cay czas prcy naprzd w poszukiwaniu nowej, apetycznej przekski.
Jak karmimy Twj wygodniay umys?
Uywamy rysunkw, bo obraz wart jest 1024 sw. Stosujemy powtrzenia, by zakodowa
na stae dane w Twojej chonnej gowie. Oddziaujemy na emocje, jestemy nieprzewidywalni,
zaskakujcy i zabawni. Stawiamy przed Tob wyzwania i zadajemy pytania, ktre
angauj Ci w proces studiowania przedstawianych zagadnie. Cay czas pobudzamy
Twj umys do aktywnego dziaania, zmuszamy go do posuszestwa a za cik
prac nagrodzimy go smakowitym ciasteczkiem w postaci wiedzy wisienka gratis!
Rozkmi to sam!
Cele stosowania wzorcw projektowych
Zaoenia, na ktrych opieraj si wzorce projektowe
Najwaniejsze i najczciej wykorzystywane wzorce projektowe
Przechowywanie i prezentacja danych
Mechanizm RMI
Wzorzec MVC
Implementacja wzorcw projektowych w aplikacjach
Przekonaj si, e nowoczesne metody nauczania mog zmieni rwnie sposb
poznawania nowoczesnych technik programistycznych

Spis treci (skrcony)


Wprowadzenie

21

1. Witamy w krainie wzorcw projektowych: wprowadzenie

33

2. Jak sprawi, by Twoje obiekty


byy zawsze dobrze poinformowane: Wzorzec Obserwator

67

3. Dekorowanie zachowania obiektw: Wzorzec Dekorator

109

4. Pizzeria zorientowana obiektowo: Wzorzec Fabryka

139

5. Obiekty jedyne w swoim rodzaju: Wzorzec Singleton

197

6. Hermetyzacja wywoa: Wzorzec Polecenie

217

7. Zdolno do adaptacji: Wzorce Adapter oraz Fasada

259

8. Hermetyzacja algorytmw: Wzorzec Metoda Szablonowa

297

9. Zarzdzanie kolekcjami: Wzorce Iterator i Kompozyt

335

10. Stan obiektu: Wzorzec Stan

403

11. Kontrola dostpu do obiektu: Wzorzec Proxy

447

12. czenie wzorcw: Wzorce zoone

517

13. Wzorce projektowe w praktyce: Nowe ycie z wzorcami

595

14. Dodatek: inne wzorce

629

Skorowidz

649

Spis treci (na serio)


Wprowadzenie
Twj mzg jest skoncentrowany na wzorcach projektowych.
W tym rozdziale Ty starasz si czego dowiedzie, a Twj mzg robi Ci przysug i nie przykada si
do zapamitywania zdobywanej wiedzy. Twj mzg myli sobie: Lepiej zostawi miejsce w pamici
na bardziej istotne informacje, na przykad: jakich dzikich zwierzt naley unika bd czy jedenie nago
na snowboardzie jest dobrym pomysem. A zatem, w jaki sposb moesz przekona swj mzg, e Twoje
ycie zaley od poznania wzorcw projektowych?

Dla kogo przeznaczona jest ta ksika?

22

Wiemy take, co sobie myli Twj mzg

23

Metapoznanie

25

Zmu swj mzg do posuszestwa

27

Zesp recenzentw technicznych

30

Podzikowania

31

6
! spis_tresci_00.indd 6

2005-06-29 10:10:32

Wprowadzenie do wzorcw projektowych

Witamy w krainie wzorcw projektowych


Kto rozwiza ju Twoje problemy. W tym rozdziale dowiesz si, dlaczego (i w jaki
sposb) moesz wykorzysta wiedz i dowiadczenia zdobyte przez innych projektantw i programistw,
ktrzy podczas pracy nad rnymi projektami zmuszeni byli wstpi na pen zdradliwych puapek ciek
i co najwaniejsze udao im si przey tak wypraw. Zanim dobrniemy do koca rozdziau, rzucimy
okiem na sposoby wykorzystywania wzorcw projektowych i przedstawimy ich zalety, poznamy kilka
podstawowych zasad projektowania zorientowanego obiektowo, a take omwimy sposb dziaania
przykadowego wzorca. Najlepsz metod zastosowania wzorca jest zaadowanie go bezporednio
do Twojego mzgu, a nastpnie zlokalizowanie obszarw w obrbie projektowanych rozwiza oraz
istniejcych aplikacji, w ktrych moesz je zastosowa. Pracujc z wzorcami projektowymi, zamiast
wielokrotnego wykorzystywania tych samych fragmentw kodu, wielokrotnie wykorzystujesz swoje
dowiadczenia.

Pamitaj,
opanowanie takich
zagadnie, jak
abstrakcyjno, dziedziczenie
i polimorfizm, nie zrobi jeszcze
z Ciebie dobrego projektanta
systemw zorientowanych
obiektowo. Prawdziwy guru zawsze
myli o stworzeniu elastycznego
projektu, ktry bdzie atwy
do serwisowania i bdzie
sobie w stanie poradzi ze
zmieniajcymi si
warunkami.

Prosta aplikacja o nazwie SymulatorKaczki

34

Jacek rozmyla o dziedziczeniu

37

A moe by tak interfejs?

38

Jedyny pewny element w procesie tworzenia oprogramowania

40

Oddzielanie tego, co si zmienia, od tego, co pozostaje niezmienione

42

Projektowanie zachowania Kaczki

43

Testowanie kodu klasy Kaczka

50

Dynamiczne ustawianie zachowania

52

Wielki diagram ukrytych zachowa

54

Relacja MA moe by lepsza ni JEST

55

Rozmawiajc o wzorcach projektowania

56

Potga wsplnego sownika wzorcw

60

W jaki sposb mog wykorzystywa wzorce projektowe?

61

Twoja skrzynka narzdziowa

64

Rozwizania wicze

66

ulated

Encaps

avior

y beh

ZG

Twj M

ace>>

<<interf

avior

FlyBeh

y()

ay
FlyNoW

Wings

y() {
- cant y!
// do nothing

FlyWith

y() {
nts duck
// impleme

Duck

FlyBeha

QuackB
swim()

perform

quack

ulated

Encaps

display(

behavio

ace>>

<<interf

ior

QuackBehav

Quack()

quack()

Fly()
)
ehavior(
ior()
kBehav
setQuac
e methduck-lik
// OTHER

perform

setFlyB

MuteQuack
Squeak
Quack
Decoy

Rubber

Object
that holds
state

Redhead

Mallard

Duck

Duck

{
display()
}
a redhead
// looks like

{
display()
}
a mallard
// looks like

Su

bje

int

t
ct Objec

Duck

Duck

){
display(
like a decoy
// looks

{
display()
k}
a rubberduc
// looks like

{
quack)
nts duck
// impleme
g
quackin

{
quack()
duckie
// rubber

{
quack()
- cant
// do nothing
quack!

squeak

OBSERWATOR

8
8
8

Dog Objec

8
Duck Objec

Mo

Automatic update/notication

Cat Object

ct
use Obje
Observers

oller

Contr

Depend
Objects ent

Grupa wzorcw projektowych

ying

vior;
vior yBeha
ehavquackB
ehavior

Client

MVC
l

est
Requ

View

Mode

az ju cakiem
Twj Kod, ter
cony poprzez
nowy i wzboga
wzorcw
zastosowanie
projektowych.

7
! spis_tresci_00.indd 7

2005-06-29 10:10:32

Wzorzec Obserwator
Jak sprawi, by Twoje obiekty byy
zawsze dobrze poinformowane

Nie przegap okazji, kiedy dzieje si co naprawd ciekawego!


Przedstawimy Ci wzorzec, ktry potrafi poinformowa inne obiekty o tym, e wydarzyo si co, czym
powinny si zaj. Co ciekawe, obiekty mog nawet samodzielnie decydowa w czasie dziaania programu
o tym, czy chc by informowane o takich wydarzeniach. Wzorzec Obserwator jest jednym z najczciej
wykorzystywanych wzorcw w pakiecie JDK (ang. Java Development Kit), a co najwaniejsze jest wrcz
niewiarygodnie uyteczny. W niniejszym rozdziale rzucimy rwnie okiem na relacje typu jeden-do-wielu
oraz tzw. lune zwizki (tak, to prawda, napisalimy lune zwizki). Korzystajc z wzorca Obserwator,
z pewnoci odmienisz swoje ycie.

Pod st a w y
ow eg o
a ni a ob ie kt
p ro g ra m ow
o
ak
tr
bs cyjn
A

Aplikacja sprawdzajca warunki pogodowe

69

Spotkanie z wzorcem Obserwator

74

Wydawca + Prenumerator = wzorzec Obserwator

75

ja
Hermetyzac

Piciominutowe przedstawienie obserwowany kontra obserwujcy

78

Polimorfizm
ie
Dziedziczen

Denicja wzorca Obserwator

81

Sia lunych zalenoci

83

Projektowanie stacji meteorologicznej

86

Implementacja stacji meteorologicznej

87

hermetyz
Poddawaj
dziczenie.
cj nad dzie
aj kompozy
Przedkad
ejsw,
zeniu interf
si na twor
uj
tr
en
nc
ko
S
entacji.
a nie implem
h
ty, w ktryc to
orzy projek
i, o ile
Staraj si tw b luno powizane
ze so
zajemnie.
obiekty s
na siebie w
e oddziauj
moliwe, ni

Java zastosowanie wbudowanego wzorca Obserwator

94

Ciemna strona klasy java.util.Observable

101

Twoja skrzynka narzdziowa

104

Rozwizania wicze

107

RELACJA JEDEN-DO-WIELU

Obiekt, ktrego stan


jest obserwowany

Ob

iekt

int

an y

w
obserwo

8
8

Obie

8
Obie

Automatyczna aktualizacja
(powiadamianie)

kt Pies

kt Kaczk

Obie

Obie

kt Kot

kt Mysz

Ob iek ty za le ne

a
g ra m ow a ni
R eg u y p ro
o
ob ie kt ow eg
zmienia.
acji to, co si

Obiekty obserwujce
(Observers)

8
! spis_tresci_00.indd 8

2005-06-29 10:10:35

Wzorzec Dekorator

Dekorowanie zachowania obiektw


W zasadzie niniejszy rozdzia moemy rwnie dobrze zatytuowa
Otwieranie oczu programistom z nadmiernymi skonnociami
do naduywania dziedziczenia. W tym rozdziale sprbujemy krytycznie przyjrze si
zwyczajowym skonnociom do naduywania mechanizmu dziedziczenia oraz nauczymy Ci sposobw
dekorowania zachowania klas w czasie dziaania programu przy uyciu pewnej formy kompozycji
obiektw. Dlaczego? Po zapoznaniu si z technikami dekoracji zachowania klas bdziesz mg wyposaa
swoje (i nie tylko) obiekty w nowe moliwoci bez koniecznoci dokonywania jakichkolwiek modyfikacji
w kodzie klas podstawowych.
Witamy w Star Caf

Zawsze sdziem,
e prawdziwi mczyni tworz
podklasy dla wszystkiego, co si tylko
do tego nadaje. Tak byo do czasu,
gdy dowiedziaem si o korzyciach,
jakie daje moliwo rozszerzania
moliwoci aplikacji na poziomie
dziaania, a nie kompilacji. A teraz
spjrzcie tylko na mnie!

110

Regua otwarte-zamknite

116

Spotkanie z wzorcem Dekorator

118

Konstruowanie zamwienia przy uyciu Dekoratorw

119

Denicja wzorca Dekorator

121

Dekorujemy nasze Napoje

122

Tworzymy kod aplikacji Star Caf

125

Dekoratory w wiecie rzeczywistym:


obsuga wejcia-wyjcia w jzyku Java

130

Tworzenie wasnych dekoratorw obsugi wejcia-wyjcia

132

Twoja skrzynka narzdziowa

135

Rozwizania wicze

136

9
! spis_tresci_00.indd 9

2005-06-29 10:10:35

Wzorzec Fabryka

Pizzeria zorientowana obiektowo


Przygotuj si do stworzenia kilku projektw, w ktrych zastosujemy
lune powizania pomidzy poszczeglnymi obiektami. Stworzenie
nowego obiektu to duo wicej ni tylko proste zastosowanie operatora new. Niebawem przekonasz si,
e proces ten jest operacj, ktra nie zawsze powinna by publicznie dostpna, a co wicej, jest operacj,
ktra czsto moe prowadzi do powanych problemw z powizaniami midzyobiektowymi. A tego by
nie chcia, prawda? Przekonaj si, w jaki sposb wzorzec Factory moe uratowa Ci z takiej opresji.

Klientami fabryki abstrakcyjnej s


dwa obiekty naszej klasy Pizzeria,
WoskaPizzeria i Amerykaska
Pizzeria.
WoskaPizzeria
utwrzPizza()

Klasa abstrakcyjna FabrykaSkadnikwPizzy jest


interfejsem, ktry okrela, w jaki sposb powinna
by tworzona rodzina spokrewnionych produktw
wszystkie skadniki, ktre s niezbdne do
zrobienia pizzy.

<<interfejs>>
Ciasto

GrubeChrupkieCiasto

<<interfejs>>
Sos

SosPomidorowy

WoskaFabrykaSkadnikwPizzy
utwrzCiasto()
utwrzSos()
utwrzSer()
utwrzWarzywa()
utwrzPepperoni()
utwrzMae()

AmerykaskaFabryka
SkadnikwPizzy
utwrzCiasto()
utwrzSos()
utwrzSer()
utwrzWarzywa()
utwrzPepperoni()
utwrzMae()

SosMarinara

<<interfejs>>
Ser

SerMozzarella

SerReggiano

<<interfejs>>
Mae

Zadaniem fabryk rzeczywistych


jest wytwarzanie odpowiednich
skadnikw pizzy. Kada
fabryka wie, w jaki sposb
naley utworzy skadniki
odpowiednie dla danego regionu.

MrooneMae

Kada fabryka wytwarza rne


implementacje tej samej rodziny produktw.

140

Pizza w Obiektowie

142

Hermetyzacja procesu tworzenia obiektw

144

Budujemy prost fabryk pizzy

145

Tworzymy denicj wzorca Simple Factory

147

Nowa struktura Pizzerii

150

Zezwalamy klasom podrzdnym na podejmowanie decyzji

151

CienkieChrupkieCiasto

<<interfejs>>
FabrykaSkadnikwPizzy
utwrzCiasto()
utwrzSos()
utwrzSer()
utwrzWarzywa()
utwrzPepperoni()
utwrzMae()

Kiedy widzisz nowy obiekt, myl o nim jako o konkretnym

wieeMae

Tworzymy Pizzeri

153

Deklarowanie metody typu Factory (fabryka)

155

Spotkanie z wzorcem Metoda Fabrykujca

161

Rwnolega hierarchia klas

162

Denicja wzorca Metoda Fabrykujca

164

Pizzeria mocno uzaleniona

167

Sprawdzamy zalenoci pomidzy obiektami

168

Zastosowanie reguy DIP

170

A w midzyczasie, na zapleczu Pizzerii

174

Rodziny skadnikw

175

Budujemy fabryki skadnikw pizzy

176

Fabryka Abstrakcyjna

183

Za kulisami

184

Denicja wzorca Fabryka Abstrakcyjna

186

Porwnanie Metody Fabrykujcej oraz Fabryki Abstrakcyjnej

190

Twoja skrzynka narzdziowa

192

Rozwizania wicze

193

10
! spis_tresci_00.indd 10

2005-06-29 10:10:36

Wzorzec Singleton

Obiekty jedyne w swoim rodzaju


Kolejnym przystankiem w naszej podry jest wzorzec Singleton,
czyli nasza przepustka do kreowania jedynych w swoim rodzaju
obiektw, posiadajcych tylko jedn instancj. By moe ucieszysz si na wie
o tym, e Singleton jest najprostszym z istniejcych wzorcw projektowych (przynajmniej pod wzgldem
kategorii stopnia zoonoci jego diagramu klas); jak by na to nie patrze, jego diagram skada si tylko
z jednej klasy! Ale nie wpadaj w eufori; niezalenie od prostoty diagramu klas tego wzorca na drodze
prowadzcej do jego implementacji napotkamy cakiem sporo wybojw i dziur. Lepiej zapnij mocno pasy
to nie bdzie takie proste, jakby mogo si wydawa.
Jeden i tylko jeden

Hershey, PA

198

May Singleton

199

Analiza klasycznej implementacji wzorca Singleton

201

Wyznania obiektu Singleton

202

Fabryka czekolady

203

Denicja wzorca Singleton

205

Ups, mamy problem

206

Zosta wirtualn maszyn Java

207

Jak sobie radzi z wielowtkowoci?

208

Wzorzec Singleton pytania i odpowiedzi

212

Twoja skrzynka narzdziowa

214

Rozwizania wicze

216

ramowania

Wzorce prog

obiektowego

jeden, doieko
amjei relacj e
ktnu
y ob
gomryitm
dzw
e.dz
yjealpo
laninia
ie
in
ie
nn
ie
dz
zm
ro
zy
ym
iu
kt
w
je
ie
pr
fin
e
iu
e
ob
onmraicnyzn
fin de
na
ysidyw
yb
ajed
j
stki
s do
na
erwdeator wodujpo
e
rfmyejda
a
or
e,
ty
al
te
at
StrateOgybs
o
go
e
in

,
or
zw
a
ne
aj
b
ek
cz
st
da
D
os
po
y
.ar

jleow
estzo
ki sp
n
doa
taor
yf
ch

wiat
za
od
ekjior
lu
poyczwh alajc
mob
e,rfzaejlesn
hjnikyzaaac
D
ieac
kt
b
ni
cy
u
na
yc
ie
lu
-wyz
ze
a
ak
w
h
tm
ic
doet
al
ich herm
tr
te
no
yc
ry
dz
i
go
in
bs
zw
on
ie
e.
go
je
je
A
ow
ni
po
dz
anfiniu
yma tylko
jew
tkktaie
ow
re
dn
da
liz
brysieyk
de
ydz
z
uszob
k
spaalok
ua
wFa
r
jago
h klpoasdr
kt
kt
j,tein
nete,mgy
icom
za
ec jStda
ia
c
a,
a
te
straan
m
ie
uj
ro
ni
nt
do
ie
zn

ie
yk
as
la
ch

kl
dz
kl
Wzorzsw
yc
on
br
y
re
bn
a
b
at
rz
od
Fa
ok
ca
al
do
a
m oda
eize
zepozw dana klas
nino
toaet
ni
zseci
aupo
ro, alo
altye
or
iewzn
M
ez
ne
ny.
alny
ni
tw
nieldo
iocz
ko
u ia
zac
asm
orzo
ktec
iezn
mw
eznob
pewnia,ktezostanieiektutuwi za
pow
algorytm
pewnia glob
iezakt
zeianinbe
or
n za
dnieak
naobwtw
c
od jesieb
yobiniestancj ob je odpowiedzialno za
Si.ngle, to
as
kl
ej
ki
ja
uywa. oferuj
chwa
jedn
tydo
zekazu
zywde.iscy
alno
rzec
i wycctznoriey Metdohotedjpr
instancji.
funkcjon
ecnkFat dostpu klas podrzdnych.
Wzorzpu
do
w
kt
obie
tworzenie

11
! spis_tresci_00.indd 11

2005-06-29 10:10:38

Wzorzec Polecenie

Hermetyzacja wywoa
W niniejszym rozdziale przeniesiemy hermetyzacj na
zupenie nowy poziom: mamy zamiar dokona hermetyzacji
wywoa metod. Zgadza si, dziki hermetyzacji wywoa metod moemy
wykrystalizowa pewne fragmenty oblicze tak, e obiekt wywoujcy obliczenia nie musi
si martwi, w jaki sposb je wykona; po prostu wykorzystuje nasz metod. Z takimi
hermetyzowanymi wywoaniami metod moemy rwnie dokonywa wielu zadziwiajco
sprytnych operacji, takich jak na przykad zapisywanie ich do dziennikw czy te ponowne
wykorzystywanie w celu zaimplementowania mechanizmu Cofnij (ang. Undo) w naszej aplikacji.

Poprosz
z
ada si
enie sk
w
Zamwi wybranych enia.
pozycji iecie zamwi
oraz z
nk
wienia
e na bla
m
an
za
pis
u
za
blankiet re zostay
kt
menu,
utwrz
Zamwi
enie()
rem

z se

nka

ka
apie

owy

od

j s

Nap

z serem
zapiekank sodowy.
i napj

Klient wie

ju, czego

chce,
ie.
zamwien
i skada

pobierzZam

wienie()

si
klienta i kiedy ju
Zamwienie od
Metoda ta
Kelnerka przyjmuje metod realizujZamwienie().
uje
przez klienta.
z tym upora, wywo
wienia zoonego
s realizacji Zam
proce
czyna
rozpo

ien

ie(

cje
Kucharz realizuje instruk
i
podane w Zamwieniu
edni
przygotowuje odpowi

218

Mamy now zabawk! Sprawdzamy, jak dziaa SuperPilot

219

Co zawiera otrzymany dysk CD-R

220

A w midzyczasie w naszym barze szybkiej obsugi

223

Przyjrzyjmy si nieco dokadniej wzajemnym interakcjom

224

Zadania i zakresy odpowiedzialnoci

225

Od Baru do wzorca Polecenie

227

Nasze pierwsze POLECENIE

229

Denicja wzorca Polecenie

232

Wzorzec Command i SuperPilot

234

Implementujemy SuperPilota

236

Sprawdzamy moliwoci naszego SuperPilota

238

Nadszed wreszcie czas, aby utworzy troch dokumentacji

241

Implementacja mechanizmu wycofywania przy uyciu stanw

246

Kady pilot powinien posiada tryb Impreza!

250

Zastosowanie makropolece

251

Kolejne zastosowania wzorca Polecenie kolejkowanie da

254

pro

du

kt

(),
apiekank
przygotujZ apj()
przygotujN

cow

r
Burge lt
Ma

ko

duj
znaj
ieniu kcje
amw stru y
Na Z szelkie in tego, ab y
si w dne do waciw eruje
b
niez towa ienie ki ujc
ug
go
w
przy k. Zam rza, pos k
ja
e
posi Kucha takimi, ).
i
prac etodam iekank(
si m gotujZap
przy

re

ali

zu

jZa

posiek.

Automatyka w domu i zagrodzie

Kolejne zastosowania wzorca Polecenie dania rejestracji

255

Twoja skrzynka narzdziowa

256

Rozwizania wicze

258

12
! spis_tresci_00.indd 12

2005-06-29 10:10:41

Wzorce Adapter oraz Fasada

Zdolno do adaptacji
W niniejszym rozdziale mamy zamiar dokona paru niesamowitych
wyczynw z dziedziny rzeczy niemoliwych, takich jak na przykad
woenie kwadratowego koka do okrgego otworu. Brzmi nierealnie? Nie
wtedy, kiedy mamy pod rk odpowiednie wzorce projektowe. Pamitasz wzorzec Dekorator? Podczas
pracy z nim owijalimy obiekty innymi obiektami tak, aby nada im nowe zachowania. Teraz mamy zamiar
postpowa tak samo, ale w nieco innym celu: chcemy sprawi, by ich interfejsy wyglday jak co, czym
nie s. Dlaczego jednak mielibymy to robi? Na przykad po to, aby zaadaptowa projekt oczekujcy
danego interfejsu do klasy, ktra implementuje zupenie inny interfejs. To jeszcze nie wszystko; skoro
ju jestemy przy tym temacie, przyjrzymy si rwnie innemu wzorcowi, ktry owija obiekty w celu
uproszczenia ich interfejsw.

Europejski standard ciennego


gniazda elektrycznego

Adapter

Standardowa wtyczka zasilajca

Adaptery s wrd nas

260

Adaptery zorientowane obiektowo

261

Wzorzec Adapter bez tajemnic

265

Denicja wzorca Adapter

267

Adaptery obiektw i klas

268

Temat dzisiejszej wieczornej pogawdki: Adapter obiektw i Adapter klas

271

Adaptery w wiecie rzeczywistym

272

Adaptujemy interfejs Enumeration do wymaga interfejsu Iterator

273

Temat dzisiejszej wieczornej pogawdki: wzorce Dekorator i Adapter

276

Nie ma to jak kino domowe

279

wiata, kamera, fasada!

282

Konstruujemy fasad naszego systemu kina domowego

285

Denicja wzorca Fasada

288

Regua ograniczania interakcji

289

Twoja skrzynka narzdziowa

294

Rozwizania wicze

296

Klient

danie

()

Klient jest zaprojektowany


niezgodnie z wymogami
interfejsu docelowego.

Obiekt
adaptowany

()
one
acz
um
nieT
da

Adapter

interfejs
obiektu
adaptowa
nego
Indyk to interfejs
adaptowanego.

y
low

rfejs

inte

doce

Adapter implementuje interfejs


docelowy i przechowuje
anego.
instancj obiektu adaptow

obiektu

fejs

uje inter

nt
impleme
dapter
IndykA Kaczka.
y
docelow

13
! spis_tresci_00.indd 13

2005-06-29 10:10:42

Wzorzec Metoda Szablonowa

Hermetyzacja algorytmw
Jestemy jak w transie: hermetyzowalimy ju proces tworzenia
obiektw, wywoania metod, zoone interfejsy, kaczki, indyki,
pizze ciekawe, co bdzie nastpne? Ot, teraz mamy zamiar zaj si
hermetyzacj fragmentw algorytmw, tak aby klasy podrzdne mogy podczepia si w rnych
miejscach wykonywanych oblicze. Co wicej, zajmiemy si rwnie regu projektowania, ktrej korzenie
wywodz si w prostej linii z Hollywood.

Zauwaylimy, e dwie
receptury s bardzo do siebie
podobne, chocia niektre
ich etapy wymagaj rnych
implementacji. Dziki temu
spostrzeeniu moglimy
uoglni receptur i umieci j
w klasie bazowej.

Herbata

2
3

Napoje
zawierajce
kofein

uoglnienie

niektre etapy
delegowane s do
klasy podrzdnej
Podklasa

2
4

Herbata

W torebk herbaty do
Dodaj cytryn.

Zagrzej
odpowied
ni ilo
wody.
Zalej wrz
tkiem od
mierzon
porcj ka
Nalej kawy
wy.
do filiank
i.
Dodaj cu
kier i ml
eko do sm
aku.

y.
edni ilo wod
Zagrzej odpowi
y do wrztku.
bat
her
bk
2 W tore
i.
baty do filiank
3 Nalej her
do smaku.
4 Dodaj cytryn

Zagrzej odpowiedni ilo wody.

Zaparz napj.

Nalej uzyskany napj do filianki.

Domieszaj do napoju odpowiednie


dodatki.

wrztku.

fein doskonale zna


Klasa NapjZKo
y receptury, cho
poszczeglne etap
etap pierwszy
sama wykonuje tylko
c realizacj
i trzeci, zostawiaj
i czwartego
etapw drugiego
ata.
klasom Kawa i Herb

Kawa

uoglnienie

niektre etapy
delegowane s do
klasy podrzdnej

Podklas

a Kawa

zon porcj
Zaparz odmier
kawy.
mleko.
i
Dodaj cukier

Tworzymy klasy reprezentujce kaw i herbat (w jzyku Java)

299

Kawa i herbata, czyli klasy abstrakcyjne

302

Cigniemy nasz projekt o krok dalej

303

Wydobywanie metody recepturaParzenia()

304

Czego ju dokonalimy?

307

Spotkanie z wzorcem Metoda Szablonowa

308

Zrbmy sobie herbat

309

Co nam daje zastosowanie metody szablonowej?

310

Denicja wzorca Metoda Szablonowa

311

Bliskie spotkania z kodem aplikacji

312

Haczyk na wzorzec Metoda Szablonowa

314

Zastosowanie haczyka

315

Testujemy nasz aplikacj

316

Regua Hollywood

318

Regua Hollywood a wzorzec Metoda Szablonowa

319

Wzorzec Metoda Szablonowa w gbokiej kniei

321

Sortowanie przy uyciu wzorca Metoda Szablonowa

322

A teraz musimy posortowa troch kaczek

323

Porwnywanie kaczek z innymi kaczkami

324

Robimy maszyn do sortowania kaczek

326

Zabawy z ramkami

328

Aplety Java

329

Temat dzisiejszej wieczornej pogawdki:


wzorce Metoda Szablonowa oraz Strategia

330

Twoja skrzynka narzdziowa

332

Rozwizania wicze

333

14
! spis_tresci_00.indd 14

2005-06-29 10:10:44

Wzorce Iterator i Kompozyt


Zarzdzanie kolekcjami

Jest wiele sposobw grupowania obiektw w kolekcje. Mona


utworzy obiekty Array, Stack, List, Hashtable. Kady z nich ma swoje zalety i wady. Jednak w pewnym
momencie klient rozpocznie iteracyjne przetwarzanie elementw kolekcji. Czy wtedy ujawnisz mu swoj
implementacj? Mam nadziej, e nie. To nie byoby profesjonalne. Nie musisz si jednak obawia,
Twoja kariera zawodowa nie jest zagroona. W tym rozdziale przedstawimy metod, ktra umoliwia
klientom przetwarzanie iteracyjne bez wiedzy o tym, jak obiekty s przechowywane. Przedstawimy te
technik tworzenia superkolekcji (ang. super collections) obiektw, ktre pozwalaj na obsug bardzo
rozbudowanych struktur danych. Bdziemy te pisa o odpowiedzialnoci obiektw.

To jest kolekcja ArrayList,


ktra przechowuje menu
poszczeglnych restauracji.

pa

nc

ake

en u

Wszystkie menu
House M

Din

erMenu

UJ

acka Menu

Menu restauracji U Jacka

Menu restauracji Pancake House


Menu restauracji Diner
tablica
Po z
ycjaMenu

Po z
ycjaMenu

Po z
ycjaMenu

Po z
ycjaMenu

klucz

klucz

Po z
ycjaMenu
klucz

2
Po z
ycjaMenu

ArrayList

Menu deserw

klucz

Po z
ycjaMenu

Po z
ycjaMenu

Po z
ycjaMenu

Hashtable

Po z
ycjaMenu

Po z
ycjaMenu

4
Po z
ycjaMenu

2
Po z
ycjaMenu

3
Po z
ycjaMenu

Po z
ycjaMenu

Kolekcja DinerMenu ma przechowywa podmenu.


Jednak nie moemy wprowadzi menu jako elementu
tablicy ze wzgldu na niezgodno typw.

Fuzja restauracji Diner i Pancake House

336

Implementacje menu ukasza i Miosza

338

Czy mona hermetyzowa iteracje?

343

Wzorzec Iterator

345

Wizanie iteratora z obiektem menu

347

Co ju mamy Szersze spojrzenie na kod naszego projektu

351

Uproszczenia po wprowadzeniu interfejsu java.util.Iterator

353

Jaki jest efekt kocowy?

355

Denicja wzorca Iterator

356

Jeden zakres odpowiedzialnoci

359

Iteratory i kolekcje

368

Iteratory i kolekcje w jzyku Java 5

369

I gdy ju miao by tak dobrze

373

Denicja wzorca Kompozyt

376

Projektujemy menu oparte na wzorcu Kompozyt

379

Implementacja klasy Menu

382

Powracamy do iteratora

388

IteratorPusty

392

Wzorce Iterator i Kompozyt razem

394

Twoja skrzynka narzdziowa

399

Rozwizania wicze

400

15
! spis_tresci_00.indd 15

2005-06-29 10:10:45

Wzorzec Stan

10

Stan obiektu
Mao znany fakt: wzorce Strategy i State to bliniaki, rozdzielone
zaraz po narodzinach. Jak ju wiemy, wzorzec Strategy umoliwi przeprowadzenie wielu
niezwykle udanych przedsiwzi opartych na zamiennie stosowanych algorytmach. Wzorzec State ma
inn rol. Jest ni wspomaganie obiektw w kontrolowaniu ich wasnych zachowa poprzez wewntrzn
zmian stanu. atwo usysze, jak mwi swoim podopiecznym: Powtarzaj za mn: jestem wystarczajco
zdolny, jestem wystarczajco dobry, dam rad to zrobi.
Krtka narada

405

Maszyny stanowe 101

406

Piszemy kod

408

Wiedziae, e to jest blisko zmiana!

412

Kopotliwy STAN rzeczy

414

Deniowanie interfejsw i klas reprezentacji stanu

417

Implementowanie klas Stan

419

Nowa wersja automatu sprzedajcego

420

Denicja wzorca Stan

428

Wzorzec Stan kontra wzorzec Strategia

429

Wzorzec Stan, werykacja projektu

435

Niemal zapomnielimy!

438

Twoja skrzynka narzdziowa

441

Rozwizania wicze

442

gdzie automatyczny sprzedawca


nigdy nie jest w poowie pusty

Brak
gum

lic
aGum

zb

=0

aG

ze

kr

an

ni e m on
a
N ie m
y
monet

li c z b

pr

et y

w k ad an

ie m on et

J e st
a
monet

um

a n ie
w yd a w
g um y

>

ie

ga

ki

zw ra ca

Automaty Sprzedajce SA

autom atu
konce pcj prac y kontr olera
Poni ej przed staw iamy nasz
lemen towa nie
. Mam y nadz iej, e zaimp
sprze dajc ego gum do ucia
zoc i
przys
spraw i Wam trudn oci. W
tego schem atu w Javie nie
my o proje kt
nowe zacho wani a, wic prosi
wa
doda
wne
zape
iemy
bdz
y do mody fikow ania.
moli wie elast yczny i atw
maty Sprz edaj ce
Auto
firmy
ie
ierow
Inyn

Guma na
da
sp r z e

16
! spis_tresci_00.indd 16

2005-06-29 10:10:45

Wzorzec Proxy

11

Kontrola dostpu do obiektu


Prbowae kiedy stosowa metod dobrego i zego?

Ty jeste tym

dobrym, ktry zrobi wszystko, o co si go poprosi, ktry jest zawsze miy i uprzejmy. Nie chcesz jednak,
eby kady mg prosi o Twoje usugi. To jest miejsce dla zego, ktry bdzie kontrolowa dostp do
Ciebie. Takie jest wanie zadanie porednikw (ang. proxy) w modelu obiektowym kontrolowanie
i zarzdzanie dostpem. Jak si przekonamy, istnieje bardzo wiele schematw takiego porednictwa.
Obiekty Proxy mog przekazywa wywoywanie metody obiektowi w innym wle internetu; bywa te,
e zastpuj wyjtkowo leniwe obiekty.

Kontrolowania stanu automatw sprzedajcych

i
Brzydk

adny

452

RMI wycieczka z przewodnikiem

455

Zdalny porednik automatu sprzedajcego

468

Porednik zdalny, za kulisami

476

Denicja wzorca Proxy

478

Porednik wirtualny

480

Projektowanie wirtualnego porednika do wywietlania okadek

482

Porednik wirtualny, za kulisami

488

Wykorzystanie mechanizmw Java API

492

Teatrzyk ochrona przedmiotw

496

Budowanie dynamicznego porednika

497

ZOO porednikw

506

Twoja skrzynka narzdziowa

508

Rozwizania wicze

509

<<interface>>
Przedmiot

<<interface>>
InvocationHandler

danie()

invoke()

Na porednika
dwie klasy.
PrawdziwyPrzedmiot
danie()

448

Rola zdalnego porednika

Proxy
danie()

az

skadaj si ter

InvocationHandler
invoke()

17
! spis_tresci_00.indd 17

2005-06-29 10:10:46

Wzorce zoone

12

czenie wzorcw
Przyszoby Ci do gowy, e wzorce mog pracowa razem? Bylimy ju
wiadkami wielu niespokojnych Pogawdek przy kominku (a omin Ci Death Match wzorcw, ktry
wydawca kaza wyrzuci) czy wsuchujc si w ich ton, mona jeszcze liczy na to, e wzorce bd ze
sob wsppracowa? Moesz wierzy lub nie, ale najbardziej wyszukane projekty obiektowe wykorzystuj
wiele wzorcw jednoczenie. Przygotuj si na kolejny poziom wiedzy o wzorcach projektowych. Czas na
wzorce zoone.

Beat jest ustawiony na 119 BPM i chcemy


zwikszy szybko do 120 BPM.

Klikamy przycisk
zwikszajcy
szybko

Widok

co powoduje wywoanie
kontrolera.

Kontroler da od modelu
zwikszenia wartoci
BPM o jeden.

Controler
Pasek beatu
pulsuje co p
sekundy.

Widok

Poniewa szybko beatu to 120


BPM,
widok jest uaktualniany co p sekundy.

tM
Bea odel
start()

ustawBPM()stop()
zBPM()
pobier

Widok zostaje
uaktualniony, aby
wywietla 120 BPM.

zmianie BPM.
Widok jest powiadamiany o
BPM().
Wywouje metod modelu pobierz

Wzorzec zoony

518

Powrt kaczek

519

Potrzebujemy adaptera gsi

522

Wprowadzamy zliczanie kwakni

524

Fabryka produkujca kaczki

526

Tworzymy stado kaczek

531

Przygotowanie interfejsu Observable

534

Co zrobilimy?

541

Widok z lotu kaczki diagram klas

542

Model-Widok-Kontroler piosenka

544

Kluczem do schematu MVC bd wzorce projektowe

546

Spojrzenie na schemat Model-Widok-Kontroler przez pryzmat wzorcw

550

Wykorzystujemy MVC do sterowania beatem...

552

Piszemy kod elementw

555

Widok

557

A teraz kontroler

560

Eksplorujemy moliwoci wzorca Strategia

563

Adaptowanie modelu

564

Nowy kontroler SerceKontroler

565

Wzorzec MVC i sie WWW

567

Model 2 a wzorce projektowe

575

Twoja skrzynka narzdziowa

578

Rozwizania wicze

579

18
! spis_tresci_00.indd 18

2005-06-29 10:10:46

Nowe ycie z wzorcami

13

Wzorce projektowe w praktyce


Ach, jeste ju gotowy na spotkanie z nowym wspaniaym wiatem
penym wzorcw projektowych Ale zanim rozpoczniesz wdrwk ku nowym
horyzontom, powi chwil na przeczytanie rozdziau powiconego pewnym szczeglnym kwestiom,
ktre pojawiaj si, gdy rozpoczynasz stosowanie wzorcw w codziennej pracy. Nie wszdzie jest tak
piknie, jak w Obiektowie. Przygotowalimy wic may przewodnik, ktry pomoe Ci odnale si
w twardej rzeczywistoci

na nowe
Przewodnik
rcami
ycie z wzo

ir porad,
podrczny zb towymi
osz, nasz
ojek
pr
i
m
ca
Przy jmij, pr
or
Ci y z wz
ktre pomog acy i zmaganiach.
pr
w codziennej

jektowy;
wi o:
wzorzec pro
my w nim m
z terminem
Ci si
W Bdzie
zwizanych
dzo mog
tym, jak bar
ozumieniach
o
i
por
ych
nie
C
w projektow
gach wzorc
rzebne;
C katalo
pot
to
jest
nie
przyda;
tam, gdzie
a wzorcw
iu stosowani
w;
C unikan
to zajcie
waniu wzorc
, e nie jest
ym klasyfiko
ych i o tym
tow
C waciw
jek
ta autorem
pro
wzorcw
sz si, jak zos
wie
niu
Do
wa
h.
inio
nyc
bra
C def
ane dla wy
zarezerwow
, jak
n powag
wzorcw;
ktujemy z rw
u, ktre tra
niach umys
icze
of Four.
w
C
iczego Gang
Zen.
mn
ie
taje
ow

trz
mis
Czterech
orcw
o Gangu
tkownik wz
imy tosam
kady uy
mie
n
inie
W Ujawn
ki pow
c
imy, jakie ksi
tw, stosuj
W Zdradz ych.
na programis
i wpywa
projektow
ych.
by przyjaci
iemy, jak zdo gi wzorcw projektow
ow
Op
W
terminolo
precyzyjn

ard
Richlm
He

Przewodnik na nowe ycie z wzorcami

596

Denicja wzorca projektowego

597

Drugie spojrzenie na denicj wzorca

599

Niech moc bdzie z Tob

600

Katalog wzorcw

601

Jak tworzy wzorce

604

Zosta autorem wzorcw projektowych

605

Porzdkowanie wzorcw projektowych

607

Mylenie wzorcami

612

Gowa pena wzorcw

615

Nie zapominaj o potdze jednolitego sownictwa

617

Pi podstawowych sposobw promowania Twojego sownictwa

618

Gang Czterech w Obiektowie

619

Podr dopiero si zaczyna

620

Inne rda informacji o wzorcach

621

ZOO pene wzorcw

622

Walka ze zem przy uyciu antywzorcw

624

Twoja skrzynka narzdziowa

626

Opuszczamy Obiektowo

627

Ralph Johnson

Gang Czterech
John
Vlissides
Erich Gamma

19
! spis_tresci_00.indd 19

2005-06-29 10:10:47

14

Dodatek inne wzorce


Nie wszyscy mog by sawni. Przez ostatnie dziesi lat wiele si w wiecie
wzorcw zmienio. Od czasu pierwszego wydania ksiki Design Patterns: Elements of Reusable
Object-Oriented Software (Wzorce projektowe) programici wykorzystali opisane w nich schematy
tysice razy. Wzorce, ktre zebralimy w tym dodatku, to dopracowane, kompletne, oficjalne
wzorce grupy GoF. Rni si od wczeniej opisanych tylko tym, e nie spotkamy ich tak czsto,
jak tych, ktrym powicilimy cae rozdziay. Nie umniejsza to ich zalet i nie powinno zniechca
do ich stosowania tam, gdzie wymaga tego sytuacja. Celem niniejszego dodatku jest zapewnienie
Ci szerszej orientacji w najatwiej dostpnych zasobach zgromadzonej przez lata wiedzy.

Klient da, aby Go


ci
pobra informacje ze
r to
Wa
struktury Kompozytu
nik

a
sk
Dodawanie nowych
rzW j() )
metod klasy Go nie
bie tne ie(
()
po owo alor ()
any
r
wpywa na kompozyt.
Zd bierzK iaka wod
o
po bierzB gl
po bierzW
po

wo wywoania
Klasa Go musi mie moli
j z klas. Jest
metody pobierzStan() kade
wadzi nowe metody,
wpro
a
miejscem, gdzie mon
y.
z ktrych bd korzysta klient

Bridge (most)

630

Builder (budowniczy)

632

Chain of Responsibility (acuch odpowiedzialnoci)

634

Flyweight (waga pirkowa)

636

Interpreter (interpreter)

638

Mediator (mediator)

640

Memento (memento)

642

Prototype (prototyp)

644

Visitor (go)

646

Stan()
pobierz
pobierzStan()
pob
ierzS
tan(
)
po
bie
rzS
Pozycja
tan
Menu
()

Go

()
tan
rzS
bie
po

Klient i Obiekt
przechodzenia

erser)
Obiekt przechodzenia (Trav
przez ca
umie przeprowadzi Gocia
w.
struktur kompozyto

Skadnik

Skorowidz

Jedyne, czego wymagamy od


klas kompozytu, to metody
pobierzStan() (i tego, eby nie
obawiay si ujawnienia).

Menu

Pozycja
Menu

Skadnik

649

20
! spis_tresci_00.indd 20

2005-06-29 10:10:47

Rozdzia 2. Wzorzec Obserwator


Jak sprawi, by Twoje
obiekty byy zawsze 

dobrze poinformowane
Cze, Jarek,
wanie dzwoni po kolei do
wszystkich z informacj, e spotkanie
naszej grupy uytkownikw wzorcw
zostao przeniesione na sobotni
wieczr. Bdziemy omawia wzorzec
Obserwator. Tak, ten wzorzec jest
najlepszy. Jarek, on jest po
prostu NAJLEPSZY!

Nie przegap okazji, kiedy dzieje si co naprawd ciekawego! Przedstawimy


Ci wzorzec, ktry potrafi poinformowa inne obiekty o tym, e wydarzyo si co, czym powinny si zaj.
Co ciekawe, obiekty mog nawet samodzielnie decydowa w czasie dziaania programu o tym, czy chc by
informowane o takich wydarzeniach. Wzorzec Obserwator jest jednym z najczciej wykorzystywanych wzorcw
w pakiecie JDK (ang. Java Development Kit), a co najwaniejsze jest wrcz niewiarygodnie uyteczny.
W niniejszym rozdziale rzucimy rwnie okiem na relacje typu jeden-do-wielu oraz tzw. lune zwizki (tak,
to prawda, napisalimy lune zwizki). Korzystajc z wzorca Obserwator, z pewnoci odmienisz swoje ycie.

to jest nowy rozdzia

rozdzial_02_kor_II.indd 67

67

2005-06-29 09:49:22

Stacja meteorologiczna
Gratulacje!
Wasz zesp wanie wygra kontrakt na budow Pogodynki 2,
najnowszej generacji internetowej stacji sprawdzajcej
i podajcej aktualn pogod.

.o .
ka sp . z o
Po go d yn
25
a
w
zo
ul . D es zc
ie gowo
0 0 -0 0 0 n

y
spprac

enie o w
wiadcz

a
ez Pastw
rania prz
g
cji
y
a
w
st
ji
j
z
e
a
rnetow
cje z ok
racji inte
e gratula
e
n
n
z
e
c
g
e
j
e
rd
wsz
se
szej najno
my zoy
ym
Chcieliby ktu na budow na
tentowan
a
tr
itym, opa
owe
m
d
o
rm kon
o
k
g
a
o
n
p
j!
z
e
i
giczn
naszym
warunk
a
e
n
c

ie

my,
z
ie
y
d
b
meteorolo
b

i
li
arta b
ledz
Chcie
giczna op ry automatycznie
eryczne). za zadanie
lo
sf
ro
o
o
tm
te
a
e
t
ienie
iaa
Stacja m
odowe, k
oraz cin
bdzie m
ach
DanePog
wilgotno ktra pocztkowo biecych warunk stkie
,
ia
obiekcie
n
e
z
c
,
to
y
o
o
j
sz
c
j
a
w
c
ra
,
k
a
y
tu
li
a ap
inform
pogod
(tempera
a utworzy wne elementy:
zyma
prognoz
tr
rm
o

e
st
a
w
ro
o
sz
p
a
d
g
z
aby W
nePogo
zie ora
nie trzy
a
d
o
ra
D
g
k
t
e
o
k
p
a
ie
n
o
b

o
e
wywietla , dane statystyczn tym w chwili, gdy
ych
zywis
c
e
rz
.
h
e
c
pogodow
si
y
a
z
cji
pomiarow
wane w c
wersja sta a rynek
aktualizo dczyty z urzdze
n
ktywiczna
e
i
p
c
rs
u
o
e
p
p
e
y
e jest to
szoci w
najnowsz

y
,
tworzenie
rz
m
p
ty
m
j
e
o
to
sz
najbli
rojektan
pamita
p
w
k
e
m
a
c
y
takich
n
h
n
c
d
in
a
je
n
oliwi
ocza ie
d
m
Musimy
asza rm
u
e
N
tw
ra
j.
e
a
t
i
n
k
z
gic
ka 2,
odzie
sza rma
meteorolo o stacji Pogodyn
acji o pog
y, aby Wa
rm
m
fo
y
b
in
li
d
I
ia
ie
n
P
. Chc
wersj A
wywietla
nia stacji
sposobw
gramowa
ro
p
I.
o
owy
P
o
wasnych
A
g
e
isaniu um
takiego
do gwn
wersj
: po podp
n
sz
l
la
moduw
e
rw
n
sp
a
ie
e
p
p
n
y biz
kady
a nam
znakomit
sztami za
dostarczy
my,
a realizuje dodatkowymi ko
oczekuje
:
rm

a
z
c
sz
a
a
o
n
g
sz
ej

e
p

a
sz
e

,
a
jl
y
n
a
i
akcji
iar obc
teraz n
Uwaam
na zakup
stacji. A
amy zam
j
je
m
e
c
p
sz
m
o
a
te
n

n
d
z
acje
z klie
oci b
jcy inform
rm patn
jcej.
wywietla an przez Was fo
acji steru
w
alfa aplik
j
rs
e
e akcepto rmy!
w
z
ora
j
jekt stacji
wspaniae
my na pro
je
u
k
e
z
c
liwoci o
Z niecierp
niem,
Z powaa

ktu
nego obie
atentowa
p
.
y
o
c
o
o
g
n
e
w
sz
dzi
od na
m jeszcze
ierajce k
re
w
e
a
ri
z
u
e
k
w
a
astw
rdo
emy do P
P.S. Pliki
dowe wyl
o
g
o
P
e
n
Da

onsun,
Janusz M

68

Prezes

Rozdzia 2

rozdzial_02_kor_II.indd 68

2005-06-29 09:49:31

Wzorzec Obserwator

Oglne spojrzenie na aplikacj


sprawdzajc warunki pogodowe
Trzema gwnymi graczami w naszym systemie s: stacja meteorologiczna
pnych trybw
to jeden z dost
e
c
e
bi
ki
moe rwnie
un
War
(zyczne urzdzenie zbierajce dane z czujnikw temperatury, cinienia
ji. Uytkownik
ac
rm
fo
in
ia
statystycznych
wywietlan
i wilgotnoci), obiekt DanePogodowe (ktry zapewnia ledzenie danych
ietlenia danych
w
lub
y
w
e
bi
so
Statystyka)
czy
nadchodzcych z tej stacji oraz aktualizuje informacje wywietlane na ekranie) zay ie dla naszego regionu (tryb gnoza).
o pogodz
(tryb Pro
oraz sam wywietlacz, ktrego zadaniem jest zobrazowanie w postaci czytelnej
ognozy pogody
te prostej pr
dla uytkownika informacji o biecych warunkach pogodowych.

Czujnik
wilgotnoci

wywietla
pobiera dane

Warunki
biece
Temp. 22 OC
Wilgotno 60%
Cinienie

Termometr

Obiekt DanePogodowe
Stacja meteorologiczna

Wywietlacz

Barometr
Elementy dostarczane przez firm
Pogodynka sp. z o.o.

Elementy, ktre musimy


zaimplementowa

Obiekt DanePogodowe wie, w jaki sposb naley komunikowa si z zyczn


stacj meteorologiczn tak, aby otrzymywa aktualne odczyty danych. Po otrzymaniu
danych obiekt aktualizuje wywietlane informacje dla trzech gwnych trybw pracy:
Warunki biece (tryb ten pokazuje informacje na temat temperatury otoczenia,
wilgotnoci oraz cinienia atmosferycznego), Statystyka oraz Prognoza.
Jeeli zdecydujemy si na zaakceptowanie tego kontraktu, naszym
zadaniem bdzie stworzenie aplikacji, ktra bdzie wykorzystywaa
obiekt DanePogodowe do aktualizacji informacji wywietlanych w trzech
gwnych trybach pracy.

jeste tutaj

rozdzial_02_kor_II.indd 69

69

2005-06-29 09:49:32

Klasa DanePogodowe

Rozpakowywanie klasy DanePogodowe


Jak zostao obiecane, nastpnego dnia rano kurier dostarczy pliki
rdowe klasy DanePogodowe. Kiedy rzucilimy okiem na jej kod,
wszystko stao si jasne:

PogodaDane
pobierzTemperatur()
pobierzWilgotno()
pobierzCinienie()
odczytyZmiana()
// inne metody

w,
z czujnik
odczyty nienia
e
ln
a
u
t
k
racaj a gotnoci oraz ci
etody zw
wil
Te trzy m : temperatury,
io
n
d
ie
w
o
odp
h
toci tyc
a
ycznego.
e s war i sposb otrzym
atmosfer
n
ia
w
a
t
s
k
u
ja
K
w
A
,
J
y o to,
ane wie
gicznej.
Nie dbam obiekt PogodaD stacji meteorolo
;
e
h
z
c
y
zmienn
formacje
owane in
zaktualiz

e
DanePogodow
ojektanci klasy
co
,
go
te
at
Jak wida, pr
m
te
wskazwk na
zostawili nam

y
o
musimy tutaj do

Pamitaj, e tryb Warunki


biece jest tylko
JEDNYM z trzech dostp
nych trybw wywietlania
informacji.

Warunki
biece
Temp. 22 C
Wilgotno 60%
Cinienie

/*
* Ta metoda jest wywoywana
* za kadym razem, kiedy zostan
zaktualizowane
* odczyty z czujnikw pogody
*
*/
public void odczytyZmiana() {
// tutaj umie odpowiedni kod
}
plik DanePogodowe.java

Nasze zadanie polega na implementacji metody


odczytyZmiana(), tak aby bya ona w stanie
automatycznie aktualizowa informacje wywietlane
w trybach Warunki biece, Statystyka oraz
Prognoza.

Wywietlacz

70

Rozdzia 2

rozdzial_02_kor_II.indd 70

2005-06-29 09:49:33

Wzorzec Obserwator

O czym wiemy do tej pory?


Specykacja nadesana z rmy Pogodynka sp. z o.o. nie bya do
koca jasna, wic musielimy si zorientowa, co tak naprawd mamy
zrobi. Podsumujmy zatem, czego dowiedzielimy si dotychczas:
pobierzTemperatur()

Klasa DanePogodowe posiada odpowiednie metody,


umoliwiajce pobieranie trzech mierzonych wartoci
(temperatury otoczenia, wilgotnoci oraz cinienia
atmosferycznego) z czujnikw fizycznych.
Metoda odczytyZmiana() jest wywoywana za kadym razem,
kiedy pojawiaj si nowe dane z czujnikw fizycznych (nie wiemy,
a w zasadzie nawet nie dbamy o to, w jaki sposb ta metoda jest
wywoana; wiemy tylko, e tak po prostu dziaa).
Musimy zaimplementowa obsug trzech trybw wywietlania
wykorzystujcych dane o pogodzie: trybu Warunki biece,
trybu Statystyka oraz trybu Prognoza. Dane wywietlane
w poszczeglnych trybach musz by na bieco aktualizowane
za kadym razem, kiedy obiekt DanePogodowe zyskuje odczyty
nowych pomiarw.
Cay system musi by atwy do rozbudowy inni projektanci
mog tworzy swoje wasne, nowe tryby wywietlania danych,
a uytkownicy mog dodawa do aplikacji bd usuwa z niej
dowoln ilo trybw wywietlania. W chwili obecnej znamy
tylko trzy pocztkowe tryby wywietlania danych (Warunki
biece, Statystyka oraz Prognoza).

pobierzWilgotno()
pobierzCinienie()

odczytyZmiana()

Statystyka
rednia
temp.: 16,6 C
Min. temp.: 10 C
Max. temp.: 25,5 C
Warunki
biece
Temp. 22 C
Wilgotno 60%
Cinienie

Drugi tryb wywietlania

Prognoza

Pierwszy tryb
wywietlania

Trzeci tryb
wywietlania

?
Przysze tryby
wywietlania

jeste tutaj

rozdzial_02_kor_II.indd 71

71

2005-06-29 09:49:33

Pierwsze kroki ze stacj meteorologiczn

Pierwszy, pozorny sukces w walce


ze stacj meteorologiczn
Poniej przedstawiamy pierwszy wariant implementacji naszego systemu
skorzystamy tu z porady, jak nam przekazali programici z rmy Pogodynka
sp. z o.o., i umiecimy nasz kod wewntrz metody odczytyZmiana():
public class DanePogodowe {
// deklaracje zmiennych obiektowych
public void odczytyZmiana() {
float temp = pobierzTemperatur();
float wilgotno = pobierzWilgotno();
float pressure = pobierzCinienie();

Pobierz najbardziej aktualne odczyty, wywoujc


odpowiednie metody umoliwiajce pobieranie
trzech mierzonych wartoci z czujnikw fizycznych
(metody zostay ju wczeniej zaimplementowane).

warunkiBieceWywietl.aktualizacja(temp, wilgotno, cinienie);


statystykaWywietl.aktualizacja(temp, wilgotno, cinienie);
prognozaWywietl.aktualizacja(temp, wilgotno, cinienie);

Aktualizacja
wywietlanych
informacji

}
// w tym miejscu mona wstawi inne metody obiektu PogodaDane
}

element
y wywietlany
Wywouje kad wywietlania najbardziej
u do
go
i przekazuje m
z odpowiednie
ci odczytw
to
aktualne war
czujnika.

Zaostrz owek
Opierajc si na pierwszej implementacji naszego systemu, okrel, ktre z wymienionych
zdarze s prawdziwe. (Zaznacz wszystkie poprawne odpowiedzi).

72

A.

Tworzymy poszczeglne implementacje,


a nie interfejsy.

D.

Poszczeglne wywietlane elementy


nie posiadaj wsplnego interfejsu.

B.

Dodanie nowego trybu wywietlania bdzie


kadorazowo wymuszao modyfikacj kodu
programu.

E.

Nie dokonalimy hermetyzacji tych


elementw aplikacji, ktre si zmieniaj.

F.

C.

Nie mamy adnych moliwoci dodawania


(lub usuwania) wybranych trybw
wywietlania podczas dziaania programu.

Naruszylimy hermetyzacj klasy


DanePogodowe.

Rozdzia 2

rozdzial_02_kor_II.indd 72

2005-06-29 09:49:34

Wzorzec Obserwator

Co jest nie tak z nasz implementacj?


Powr na chwil mylami do tych wszystkich poj i regu, o ktrych
wspominalimy w rozdziale 1
public class PogodaDane {
// deklaracje zmiennych obiektowych
public void odczytyZmiana() {
float temp = pobierzTemperatur();
float wilgotno = pobierzWilgotno();
float pressure = pobierzCinienie();

Obszar zmian, powinnimy


zatem dokona jego
hermetyzacji.

warunkiBieceWywietl.aktualizacja(temp, wilgotno, cinienie);


statystykaWywietl.aktualizacja(temp, wilgotno, cinienie);
prognozaWywietl.aktualizacja(temp, wilgotno, cinienie);
}

mentacji
W przypadku tworzenia poszczeglnych imple
ani
a
wani
doda
nie mamy adnych moliwoci
ywania
usuwania wywietlanych elementw bez dokon
.
ramu
prog
e
kodzi
w
ji
modyfikac

uywa
Wyglda na to, e przynajmniej staramy si
ych
ietlan
wyw
dla
fejsu
inter
litego
wsplnego, jedno
d
meto
daj
posia
stkie
Wszy

ntw
eleme
oci
aktualizacja(), ktrej argumentami s wart
nia
cinie
oraz
i
tnoc
wilgo
enia,
temperatury otocz
o.
czneg
atmosfery

Hmmmm, ja
wiem, e jestem tutaj nowy,
ale poniewa znajdujemy si wanie
w rozdziale dotyczcym wzorca
Obserwator, moe w kocu
zaczlibymy z niego korzysta?

Rzucimy teraz okiem na wzorzec


Obserwator, a nastpnie powrcimy
do naszej aplikacji i pokaemy,
w jaki sposb mona zastosowa
go do aplikacji obsugujcej stacj
meteorologiczn.

jeste tutaj

rozdzial_02_kor_II.indd 73

73

2005-06-29 09:49:34

Spotkanie z wzorcem Obserwator

Spotkanie z wzorcem Obserwator


Zapewne wiesz, w jaki sposb dziaa prenumerata gazet i czasopism:

Wydawca nowej gazety lub czasopisma rozpoczyna swoj dziaalno i na rynku


pojawia si nowy tytu prasowy.

Zamawiasz prenumerat u danego wydawcy i od tego momentu za kadym razem,


kiedy pojawia si nowe wydanie, zostaje Ci ono dostarczone. Cao dziaa tak dugo,
jak dugo pozostajesz prenumeratorem danego tytuu prasowego.

Jeeli nie chcesz wicej otrzymywa danej gazety lub czasopisma, po prostu
wypowiadasz prenumerat i od tego momentu nowe wydania przestaj do Ciebie
dociera.

Jak dugo dany wydawca (czy te dany tytu prasowy) istnieje na rynku, tak dugo
rni ludzie, firmy, hotele, linie lotnicze itp. bd ustawicznie dokonyway nowych
prenumerat i wypowiaday stare prenumeraty.

Tsknisz za nowymi informacjami


z Obiektowa? Nie ma innego wyjcia,
musimy zaprenumerowa tamtejsz
gazet codzienn!

74

Rozdzia 2

rozdzial_02_kor_II.indd 74

2005-06-29 09:49:34

Wzorzec Obserwator

Wydawca + Prenumerator
= wzorzec Obserwator
Jeeli rozumiesz zasady prenumerowania gazet i czasopism, oznacza to,
e cakiem dobrze rozumiesz zasady funkcjonowania wzorca Obserwator,
z tym tylko, e we wzorcu zamiast wydawcy wystpuje PODMIOT
(obiekt obserwowany), a zamiast prenumeratorw wystpuj OBIEKTY
OBSERWATORZY (obiekty obserwujce).
j
Obiekty obserwujce posiadaj subskrypc
ch
dany
ch
wany
alizo
zaktu
anie
myw
na otrzy
za kadym razem, kiedy informacje, jakie
nie.
posiada obiekt obserwowany, ulegaj zmia

Przyjrzyj si, jak to wyglda:

obserwowanym ulegn
Kiedy dane w obiekcie
ty
iek
(ob
e
iekty obserwujc
zmianie, wszystkie ob
.
ne
wa
mo
or
inf
j o tym po
Obserwatorzy) zosta
dzania
Podmiot zarz
mi.
ny
da
i
m
pewny

Obiekt Pies

2
2

liczba

Obi cakowita any


ekt o wow
b s er
Jeeli nastpi zmiana danych, ich
nowe wartoci s przekazywane
do obiektw obserwujcych.

O b i e k t Kaczk

t obserwatorem,
Ten obiekt nie jes
poinformowany
wic nie zostaje
zachodz
ie
o zmianach, jak
obserwowanego.
tu
iek
w danych ob

Obiekt Kot

Obie

kt Mysz

Obiekty obserwujce

jeste tutaj

rozdzial_02_kor_II.indd 75

75

2005-06-29 09:49:35

Dzie z ycia wzorca Obserwator

Dzie z ycia wzorca Obserwator


ie
mn
z
s
pi
2
(do w)
in e e n t
liczba
cakowita
jm b
ru skry
Obi
t
s
an
b
ek t o
u
je
bserwow
re sty s
a
z li
do

Obiekt Pies

Obiekt Kaczka pojawia si i nastpnie


informuje obiekt obserwowany,
e chciaby zosta jego obserwatorem.

Obiekt Kaczka jest teraz oficjalnie


uznanym obserwatorem.
Kaczka jest podekscytowana
znajduje si ju na licie
i z niecierpliwoci oczekuje
na nadejcie pierwszych informacji
od obiektu obserwowanego.

Obiek

t Kacz

Obie

ka

kt Mysz

Obiekty obserwujce

2
liczba
cakowita

Ob i
ekt o wowa
bser

ny

Obiekt Kaczka tak naprawd chce


tylko jednego: danych, jakie obiekt
obserwowany wysya za kadym
razem, kiedy zmienia si jego stan.

Obiekt Kot

Obiekty obserwujce

W takiej sytuacji obiekt Kaczka


oraz pozostae obiekty obserwujce
otrzymuj powiadomienie, e obiekt
obserwowany zmieni stan.

8
liczba
cakowita

Ob i
ekt o wowa
bser

ny

Obiekt obserwowany
otrzymuje nowe dane!

8
8
8

Obiekt Pies

8
Obie

kt kaczk

Obie

Obiekt Kot

kt Mysz

Obiekty obserwujce

76

Rozdzia 2

rozdzial_02_kor_II.indd 76

2005-06-29 09:49:35

Wzorzec Obserwator

8
liczba
cakowita

Obi
ek t o

Obiekt Pies

an u s
u
bserwow
m

Obiekt Mysz prosi o usunicie z listy


obserwatorw.
Mysz otrzymywaa aktualizacje danych
z obiektu obserwowanego od wiekw
nic dziwnego zatem, e w kocu jej
si znudzio i postanowia zrezygnowa
z bycia obserwatorem.

nie

z li

sty

sub

Obie

skr

ybe

nt

kt kaczk

Obiekt Kot

w
Obie

kt Mysz

Obiekty obserwujce

8
Obi
ek t o

Obiekt obserwowany potwierdza


przyjcia dania Myszy
i usuwa j z listy obserwatorw.

Obiekt Pies

an
bserwow

Myszy ju tu nie ma!

liczba
cakowita

Obie

Obie

kt kaczk

Obiekt Kot

kt Mysz

Obiekty obserwujce

Obiekt obserwowany
ponownie zmieni stan.

14
liczba
cakowita

14

Ob i
ekt o wowa
bser

ny

Wszystkie obiekty obserwujce zostaj


o tym fakcie powiadomione; wyjtkiem
jest tutaj Mysz, ktra ju nie znajduje
si na licie subskrybentw. Nie mw
tego nikomu, ale tak naprawd nasza
Mysz w skrytoci ducha tskni za
biecymi komunikatami by moe
pewnego dnia wystpi ona z prob
o ponowne zaliczenie jej w poczet
obserwatorw.

Obiekt Pies

14
14
Obie

Obie

kt kaczk

Obiekt Kot

kt Mysz

Obiekty obserwujce

jeste tutaj

rozdzial_02_kor_II.indd 77

77

2005-06-29 09:49:36

Piciominutowe przedstawienie

Piciominutowe przedstawienie
obserwowany kontra obserwujcy
W dzisiejszym skeczu dwch zakrconych projektantw oprogramowania
spotyka prawdziwego owc talentw
Mwi Robert.
Szukam nowego miejsca pracy
w charakterze projektanta systemw
opartych na Javie. Mam picioletnie
dowiadczenie oraz

Hmmm,
oczywicie, Ty
i kto tylko jeszcze bdzie
chcia, mj chopcze. Wanie
umieszczam Ci na mojej licie
projektantw systemw Java.
Nie dzwo do mnie, to ja do
Ciebie oddzwoni!

2
owca talentw (Podmiot)
Umieszcz
Twoje nazwisko na
mojej licie. Dziki temu
bdziesz informowana
na bieco, razem
z pozostaymi
obserwatorami.

Projektant nr 1

Cze,
mam na imi Joanna,
napisaam ju wiele
systemw wykorzystujcych EJB.
Jestem zainteresowana dowolnym
stanowiskiem pracy w dziale
zajmujcym si projektowaniem
systemw Java.

4
3
Projektant nr 2
Obiekt obserwowany
(Podmiot)

78

Rozdzia 2

rozdzial_02_kor_II.indd 78

2005-06-29 09:49:36

Wzorzec Obserwator
W midzyczasie ycie Roberta i Joanny biego swoim
zwykym torem; jeeli pojawiaa si jaka oferta pracy
dla projektantw Javy, otrzymywali informacje krtko
mwic, zostali obserwatorami.

Dziki! Za
chwil wysyam
swoje CV.

Hej,
obserwatorzy,
wanie si dowiedziaem,
e firma JavaBeans ma
kilka wakatw na stanowiskach
zwizanych z projektowania
systemw Java bierzcie si
za to!

Ten facet to jaki wariat,


mam go gdzie. Sama
sobie znajd prac.

Buehehehe,
masz to jak w banku,
kochanie!

7
Obserwator
Obserwator

Arghhh!
Zapamitaj moje sowa,
Joasiu, e jeeli tylko bd
mg uczyni co w tym kierunku,
nigdy wicej nie uda Ci si
znale pracy w tym miecie.
Skrelam Ci z mojej listy!!!

Obiekt obserwowany

Joanna znajduje nowego pracodawc.


Moesz
mnie usun ze
swojej listy, sama
sobie znalazam
prac!

8
Obserwator

Obiekt obserwowany
jeste tutaj

rozdzial_02_kor_II.indd 79

79

2005-06-29 09:49:36

Definicja wzorca Obserwator

Dwa tygodnie pniej


Joanna wielce sobie ceni swoje obecne ycie i nie musi
ju odgrywa roli obserwatora. Jest rwnie bardzo
zadowolona, e nowa firma zaproponowaa
jej bardzo dogodne warunki finansowe, tym lepsze,
e nie musiaa dodatkowo opaci usug owcy
talentw.

Ale co si stao z naszym drogim Robertem? Syszelimy,


e pobi owc talentw na jego wasnym podwrku. Jest teraz
nie tylko obserwatorem, ale rwnie posiada swoj wasn list
subskrybentw (obserwatorw), ktrych powiadamia o pojawieniu
si nowych ofert na rynku pracy. Krtko mwic, Robert jest
teraz zarwno obserwujcym, jak i obserwowanym.

80

Rozdzia 2

rozdzial_02_kor_II.indd 80

2005-06-29 09:49:37

Wzorzec Obserwator

Definicja wzorca Obserwator


Jeeli bdziesz prbowa w jaki sposb zobrazowa sobie wzorzec Obserwator,
to zapewne szybko dojdziesz do wniosku, e przedstawiony wczeniej przykad
z wydawnictwem i prenumerat periodykw prasowych stanowi jego znakomit wizualizacj.
Jednak w wiecie rzeczywistym wzorzec Obserwator jest zazwyczaj definiowany nastpujco:

Wzorzec Obserwator
definiuje relacj jeden-do
-wielu pomidzy obiektami
danego zbioru obiektw.

Wzorzec Obserwator definiuje pomidzy obiektami relacj


jeden-do-wielu w taki sposb, e kiedy wybrany obiekt
zmienia swj stan, to wszystkie jego obiekty zalene zostaj
o tym powiadomione i automatycznie zaktualizowane.

Porwnajmy zatem powysz definicj z tym, o czym do tej pory


mwilimy na temat wzorca:

Kiedy stan jednego


z obiektw zmienia si,
wszystkie jego obiekty
zalene zostaj o tym
powiadomione

RELACJA JEDEN-DO-WIELU
Obiekt, ktrego
stan jest
obserwowany

bserwow

Obiekt Pies

8
Obie

kt kaczk

Obie

Automatyczna aktualizacja (powiadamianie)

Obiekt Kot

kt Mysz

zalene

an

liczba
cakowita

Obi
ek t o

8
8
8

Obiekty

Obiekty obserwujce

Obiekt obserwowany oraz obiekty obserwujce s ze sob powizane relacj jeden-do-wielu. Obiekty obserwujce
s zalene od obiektu obserwowanego, co przejawia si w ten sposb, e jeeli obiekt obserwowany zmienia swj
stan, to wszystkie obiekty obserwujce zostaj o tym powiadomione. W zalenoci od sposobu, w jaki realizowane jest
powiadamianie, obiekty zalene mog by rwnie automatycznie aktualizowane (mog otrzymywa nowe dane od
obiektu obserwowanego).
Jak si niebawem sam przekonasz, wzorzec Obserwator moe by implementowany na kilka rnych sposobw,
aczkolwiek wikszo z nich obraca si dookoa tworzenia osobnych klas, ktre posiadaj interfejsy Podmiot oraz
Obserwator.
Rzumy na to okiem
jeste tutaj

rozdzial_02_kor_II.indd 81

81

2005-06-29 09:49:37

Lune zalenoci

Definicja wzorca Obserwator


diagram klas

lnymi
bdce potencja
Wszystkie obiekty
a interfejs
w
to
sz implemen
mu
i
am
or
at
rw
se
ob
tylko jedn
interfejs posiada
Obserwator. Ten
wywoywana,
cja(), ktra jest
metod, aktualiza
swj stan.
i
rwowany zmien
kiedy obiekt obse

Kady obiekt obserwowany


go
ystuj
moe mie wielu obserwatorw.
wykorz rwatorw
y
t
k
ie
obse
t. Ob
e
io
z
r
m
e
d
t
o
k
chara
ty
erfejs P
Oto int rowania si w h danych z lis
t
ic
s
do reje sunicia swo
Obiekty
<<interfejs>>
<<interfejs>>
ou
obserwujce
oraz d torw.
Podmiot
Obserwator
a
w
r
e
s
zarejestrujObserwatora()
ob
aktualizacja()
usuObserwatora()
si
mu
wany zawsze
powiadomObserwatorw()
Dany obiekt obserwo
owany interfejs
nt
me
ple
posiada zaim
tod pozwalajcych
Podmiot. Oprcz me
ra
i usunicie obserwato
na zarejestrowanie
ie
wn
posiada r
obiekt obserwowany
Obiekt
serwatorw(), ktra
Ob
ObiektPodmiot
ObiektObserwator
om
ad
wi
po
obserwujcy
metod
ia
ian
am
ad
wi
po
do
(Subject)
a
an
yw
yst
rz
zarejestrujObserwatora()
{...}
aktualizacja()
ko
wy
t
jes
usuObserwatora() {...}
// inne metody specyficzne
uacji, kiedy zmieni si
obserwatorw w syt
powiadomObserwatorw()
dla danego obserwatora
go.
ne
wa
wo
ser
ob
{...}
tu
stan obiek

rwnie
rwowany moe
Dany obiekt obse
do
e
e metody suc
posiada odrbn
(wicej
u
an
st
erania jego
ustawiania i pobi
imy nieco
w
ta
ds
ze
pr
n temat
informacji na te
niej).

pobierzStan()
ustawStan()

Poszczeglne obiekty obserwujce mog by obiektami dowolnej


klasy, ktra posiada zaimplementowany interfejs Obserwator.
Aby otrzymywa kolejne powiadomienia (lub aktualizacje),
kady obiekt obserwujcy musi si zarejestrowa u danego
obiektu obserwowanego.

Nie istniej

gupie pytania

P:

Co to wszystko
ma wsplnego z relacj
jeden-do-wielu?

O:

Zgodnie z zaoeniami wzorca


Obserwaror to obiekt obserwowany
jest obiektem, ktry posiada okrelony
stan i kontroluje go. Zatem wynika std,
e mamy tylko JEDEN obiekt, ktry
posiada stan. Z kolei obiekty obserwujce
wykorzystuj ten stan, nawet jeeli nie s

82

Rozdzia 2

jego wacicielami. Krtko mwic, istnieje


wielu obserwatorw, ktrzy polegaj na
informacjach docierajcych z obiektu
obserwowanego, przekazywanych
w momencie, kiedy jego stan ulega
zmianie. Moemy zatem powiedzie,
e jest to relacja pomidzy JEDNYM
obiektem obserwowanym, a WIELOMA
obiektami obserwujcymi.

P:

Gdzie zatem w tym caym


ukadzie znajduje si zaleno?

O:

Poniewa to obiekt obserwowany


jest jedynym i wycznym wacicielem
danych, aktualizacja obiektw
obserwujcych jest zalena od zmiany
stanu obiektu obserwowanego. Takie
podejcie pozwala na stosowanie bardziej
przejrzystego procesu projektowania
(zorientowanego obiektowo), ni miaoby
to miejsce w sytuacji, kiedy wiele obiektw
moe sterowa tym samym zestawem
danych.

Wzorzec Obserwator

Sia lunych zalenoci


Kiedy dwa obiekty s ze sob luno powizane, mog ze sob wsppracowa, ale z drugiej strony wzajemnie nie wiedz o sobie zbyt wiele.
Wzorzec Obserwator zapewnia utworzenie takiej struktury obiektw,
w ktrej obiekty obserwowane s luno powizane ze swoimi obiektami
obserwujcymi.
Dlaczego?

Nowych obserwatorw moemy dodawa w dowolnym momencie. Poniewa jedynym elementem, na ktrym
opiera si dziaanie obiektu obserwowanego, jest lista zarejestrowanych obiektw implementujcych interfejs
Obserwator, nowe obiekty obserwujce mog by dodawane w dowolnie wybranej chwili. W praktyce
w czasie dziaania programu moemy wymieni dowolny, zarejestrowany obiekt obserwujcy na inny
a obiekt obserwowany niezalenie od tego bdzie sobie funkcjonowa tak samo, jak do tej pory.
Jak atwo si domyli, w analogiczny sposb moemy usun w dowolnej chwili dowolny obiekt obserwujcy.
Dodawanie nowych typw obserwatorw nigdy nie pociga za sob koniecznoci modykacji obiektu
obserwowanego. Powiedzmy, e pojawia nam si (nie wnikamy, skd) nowa klasa, ktrej obiekty musz
by obserwatorami. Aby doda je do listy subskrybentw, nie musimy modykowa kodu obiektu
obserwowanego wszystko, czym musimy si zaj, to implementacja w nowym obiekcie interfejsu
Obserwator i zarejestrowanie nowego obserwatora na licie obiektu obserwowanego. Ten ostatni zupenie
nie bdzie si tym przejmowa; jego zadaniem jest po prostu dostarczanie okrelonych informacji
do wszystkich obiektw, ktre zostay zarejestrowane i implementuj interfejs Obserwator.

Ile r
n
moes ych rodza
j
z tuta
j nalic w zmian
zy?

Jedyn informacj, jak obiekt obserwowany posiada o obiekcie obserwujcym, jest to, e obiekt
obserwujcy posiada pewien okrelony interfejs (interfejs Obserwator). Obiekt obserwowany nie musi nawet
wiedzie, do jakiej klasy naley obiekt obserwujcy i czym si on zajmuje. Nie musi te zna adnej tego typu
informacji.

Zarwno obiekty obserwowane, jak i obiekty obserwujce mog by niezalenie od siebie wielokrotnie
wykorzystywane. Jeeli dla ktrego z obiektw obserwowanych lub obserwujcych znajdziesz inne
zastosowanie, moesz je atwo wykorzysta, poniewa s one ze sob bardzo luno powizane.
Zarwno zmiany wprowadzane do obiektu obserwowanego, jak do obiektw obserwujcych nie maj
wzajemnie na siebie adnego wpywu. Poniewa wspomniane dwa rodzaje obiektw s ze sob luno
powizane, moemy je niemal dowolnie modykowa tak dugo, jak dugo poszczeglne obiekty bd
speniay zaoenie posiadania poprawnie zaimplementowanego interfejsu Podmiot bd Obserwator.

Regua projektowania
Staraj si tworzy projekty, w ktrych obiekty
s ze sob luno powizane i, o ile to moliwe,
nie oddziauj na siebie wzajemnie.

Projekty charakteryzujce si lunymi powizaniami pomidzy obiektami pozwalaj na tworzenie


bardzo elastycznych systemw, w atwy sposb adaptujcych si do wprowadzanych zmian,
co zawdziczaj minimalizacji wzajemnych zalenoci wewntrznych.
jeste tutaj

rozdzial_02_kor_II.indd 83

83

2005-06-29 09:49:38

Plan utworzenia stacji meteorologicznej

Zaostrz owek
Zanim przejdziesz do kolejnej sekcji, sprbuj naszkicowa struktur klas,
jakiej bdziesz potrzebowa do zaimplementowania oprogramowania stacji
meteorologicznej, wczajc w to klas DanePogodowe oraz jej elementy
odpowiadajce za wywietlanie. Upewnij si, e rysowany diagram pokazuje,
w jaki sposb poszczeglne elementy s ze sob poczone, a take wyjania,
w jaki sposb inny programista lub projektant moe doczy swj wasny, nowy
tryb wywietlania.
Jeeli potrzebujesz maej pomocy, przeczytaj to, co zamiecilimy na nastpnej
stronie; wyglda na to, e Twoje koleanki z boksu obok ju rozpoczy dysput
na temat tego projektu.

84

Rozdzia 2

rozdzial_02_kor_II.indd 84

2005-06-29 09:49:38

Wzorzec Obserwator

Zasyszane w ssiednim boksie


Wracajc do tematu projektu stacji meteorologicznej... wyglda na to,
e Twoje koleanki z boksu obok zaczy ju myle o rozwizaniu tego zadania

Sa

a:
ndr

A wic, w jaki
sposb bdziemy to co
budowa?
Maria: Dobrze wiedzie, e bdziemy si posugiwa wzorcem Obserwator.
To zdecydowanie pomaga.
Sandra: Taak ale w jaki sposb go zaimplementujemy?
Maria: Hmmm rzumy jeszcze raz okiem na definicj tego wzorca:
Wzorzec Obserwator definiuje pomidzy obiektami relacj jeden-do-wielu w taki sposb, e kiedy wybrany obiekt zmienia swj stan,
to wszystkie jego obiekty zalene zostaj o tym powiadomione i automatycznie zaktualizowane.

Maria: Jak si nad tym spokojnie zastanowi, wychodzi na to, e taka definicja ma sens. Nasza klasa,
DanePogodowe, jest wanie tym jednym, a wieloma s poszczeglne tryby wywietlania informacji o pogodzie.
Sandra: Racja. Klasa DanePogodowe posiada rwnie swoje stany to znaczy, mam na myli temperatur otoczenia,
wilgotno oraz cinienie atmosferyczne, a te wartoci definitywnie bd si zmienia na przestrzeni czasu.
Maria: Fakt, a kiedy odczyty tych parametrw bd si zmieniay, bdziemy musieli poinformowa o tym
wszystkie elementy odpowiedzialne za wywietlanie, tak aby mogy przetwarza nowe wartoci zgodnie ze swoim
przeznaczeniem.
Sandra: wietnie! Myl, e ju wiem, w jaki sposb moemy zastosowa wzorzec Obserwator do naszego
systemu ledzenia pogody wedug wskaza czujnikw stacji meteorologicznej.
Maria: Ale cigle pozostaje kilka spraw, ktre musimy rozway, a co do ktrych nie jestem cakowicie pewna,
e je dobrze rozumiem.
Sandra: Na przykad?
Maria: Na przykad to, w jaki sposb dostarczymy wyniki pomiarw poszczeglnych parametrw do elementw
odpowiedzialnych za wywietlanie danych.
Sandra: No c, przypomnij sobie, jak wyglda diagram wzorca Obserwator. Jeeli naszym obiektem
obserwowanym zostanie obiekt DanePogodowe, a obiektami obserwujcymi bd elementy (obiekty)
odpowiedzialne za wywietlanie poszczeglnych informacji, to aby otrzymywa aktualne informacje, obiekty takie
bd musiay najpierw zosta zarejestrowane przez obiekt obserwowany, prawda?
Maria: Tak a kiedy obiekt obserwowany bdzie zna list swoich subskrybentw, wystarczy, e bdzie wywoywa
odpowiednie metody, ktrych zadaniem bdzie przekazywanie im zaktualizowanych danych z pomiarw.
Sandra: Musimy jednak pamita, e kady wywietlany element moe by zupenie inny Wic tak sobie myl,
gdzie jest miejsce na wprowadzenie wsplnego interfejsu? Pomimo, e poszczeglne elementy mog by zupenie
odmiennych typw, wszystkie powinny posiada taki sam interfejs, tak aby obiekt DanePogodowe wiedzia, w jaki
sposb wysya im wyniki poszczeglnych pomiarw.
Maria: Wiem, o co Ci chodzi. Wynika z tego, e kady obiekt odpowiedzialny za wywietlanie bdzie posiada
metod, powiedzmy, aktualizacja(), ktra bdzie wywoywana przez obiekt DanePogodowe.
Sandra: i ta metoda aktualizacja() bdzie zdefiniowana w wsplnym interfejsie, zaimplementowanym
we wszystkich obiektach.

jeste tutaj

rozdzial_02_kor_II.indd 85

85

2005-06-29 09:49:38

Projektowanie stacji meteorologicznej

Projektowanie stacji meteorologicznej


Jak poniszy diagram wyglda w porwnaniu z Twoim?
zetwarzanie
wiedzialne za pr
po
od
ty
iek
ob
ie
Wszystk
plementowany
dy posiadaj zaim
go
po
ia
w
tr
me
ra
pa
izanie udostpn
ator. Takie rozw
fejs,
er
int
y
ln
sp
interfejs Obserw
w
u Podmiot
em
an
ow
rw
se
ob
i
obiektow
alizowanych na
przesyanie aktu
tw
pozwalajcy na
podlegych obiek
ich
tk
do wszys
bieco informacji
obserwujcych.

ca
dmiot,
fejs Po mo.
r
e
t
in
sz
ajo
Oto na wyglda zn
a
n
in
w
o
p

Obiekty obserwujce

<<interface>>
Podmiot

<<interface>>
Obserwator

zarejestrujObserwatora()
usuObserwatora()
powiadomObserwatorw()

Ob

DanePogodowe

ser w

ujc

WarunkiBiece
aktualizacja()
wywietl() {// wywietl
biece wartoci pomiarw}

NowyTrybWywietlania
aktualizacja()
wywietl() {// wywietlaj
co innego w oparciu
o otrzymywane wartoci
pomiarw }

zarejestrujObserwatora()
usuObserwatora()
powiadomObserwatorw()
pobierzTemperatur()
pobierzWilgotno()
pobierzCinienie()
odczytyZmiana()

we posiada
Obiekt DanePogodo
owany
obecnie zaimplement
.
interfejs Podmiot

<<interface>>
WywietlElement
wywietl()

aktualizacja()

ob
iekt

Utwrzmy rwnie wsplny


interfejs, ktry bd posiaday
wszystkie obiekty odpowiedzialne
za wywietlanie informacji na ekranie.
Poszczeglne obiekty bd musiay mie
zaimplementowan metod wywietl().

Ten element wywiet


la
biece wartoci pomi
arw,
przekazywane przez
obiekt
DanePogodowe.

StatystykaWywietlanie
aktualizacja()
wywietl() {// wywietl
warto redni, minimaln
oraz maksymaln poszczeglnych wielkoci}

Ten element wylicza wartoci


rednie danej wielkoci
i odszukuje wartoci minimalne
oraz maksymalne, a nastpnie
wywietla je na ekranie.

PrognozaWywietlanie
aktualizacja()
wywietl() {// wywietlaj
biec prognoz pogody }

Ten element wywietla


aktualn prognoz
pogody utworzon
w oparciu o wskazania
barometru (odczyty
wielkoci cinienia
atmosferycznego).

Podmiot
wykorzystywa interfejsy
Projektanci z innych firm mog
jcych
etla
wi
wy
w
nia wasnych obiekt
oraz Obserwator do tworze
).
nia
etla
wi
ch trybw wy
dane (do tworzenia wasny

Te trzy obiekty odpowiedzialne za wywietlanie powinny rwnie


posiada strzak (wskanik) oznaczon obiekt obserwujcy
i prowadzc do obiektu DanePogodowe, ale jelibym je tutaj dorysowa,
cay diagram zaczby nieco przypomina spaghetti

86

Rozdzia 2

rozdzial_02_kor_II.indd 86

2005-06-29 09:49:39

Wzorzec Obserwator

Implementacja stacji meteorologicznej


Rozpoczniemy teraz implementacj aplikacji obsugujcej stacj meteorologiczn, wykorzystujc do tego celu
przedstawiony diagram klas oraz biorc pod uwag wnioski pynce z rozmowy Marii i Sandry (zapis rozmowy
zamiecilimy kilka stron wczeniej). W nieco dalszej czci niniejszego rozdziau przekonasz si, e Java
posiada pewne wbudowane mechanizmy obsugi wzorca Obserwator, aczkolwiek w chwili obecnej mamy
szczery zamiar nieco pobrudzi sobie rczki, samemu zabra si do roboty i stworzy niezbdny kod. Co prawda,
wbudowane mechanizmy Javy pozwalaj na skorzystanie z nich w niektrych wypadkach, ale samodzielne
stworzenie odpowiednich klas gwarantuje o wiele wiksz elastyczno caego systemu (a zarczam, e nie
jest to takie trudne). Dobrze, zatem zacznijmy od stworzenia odpowiednich interfejsw (pliki Podmiot.java,
Obserwator.java oraz WywietlElement.java):
Metody pobieraj jako argument obiekt
typu Obserwator, czyli konkretnie obiekt,
ktry ma zosta zarejestrowany na licie
zarejestrowanych bd usunity z tej listy.

public interface Podmiot {


public void zarejestrujObserwatora (Obserwator o);
public void usuObserwatora(Obserwator o);
public void powiadomObserwatorw(); Ta metoda jest wywoywana w celu powiado
mienia
}
wszystkich obserwatorw o tym, e stan obiektu
Wszystkie obiekty obserwujce
obserwowanego zmieni si.
posiadaj zaimplementowany
interfejs Obserwator, std
public interface Obserwator {
wszystkie musz mie take
public void aktualizacja(float temp, float wilgotno, float cinienie); zaimplementowan metod
}
aktualizacja(). Wanie w tym
Te zmienne odpowiadaj wartociom stanu, jakie obiekty obserwujce otrzymuj
miejscu wykorzystamy sugestie,
od obiektu obserwowanego, kiedy zmieniaj si odczyty parametrw pogody.
jakie pady podczas rozmowy
Marii z Sandr, i tutaj bdziemy
przekazywa wyniki kolejnych
public interface WywietlElement{
pomiarw do poszczeglnych
public void wywietl();
obserwatorw.
}
Interfejs WywietlElement posiada tylko jedn metod,
wywietl(), ktr bdziemy wywoywa w sytuacji,
kiedy niezbdne bdzie wywietlanie danego elementu
naekranie.

WYT
UMYS

Maria i Sandra mylay, e przekazywanie wynikw pomiarw bezporednio do obiektw obserwujcych jest
najprostszym sposobem na ich uaktualnianie. Czy zgadzasz si z ich zdaniem? Wskazwka: czy w naszej aplikacji jest
jaki obszar, ktry moe w przyszoci ulec zmianie? Jeeli taka zmiana nastpi, to czy bdzie ona wystarczajco dobrze
hermetyzowana, czy te bdzie jednak wymagaa dokonania modyfikacji wielu innych czci kodu aplikacji?
Czy moesz pomyle nad opracowaniem nowych sposobw przekazywania uaktualnionych odczytw do obiektw
obserwujcych?
Nie musisz si przejmowa powrcimy jeszcze do problemu zatwierdzenia projektu aplikacji po zakoczeniu wstpnej
fazy jej implementacji.
jeste tutaj

87

Implementacja stacji meteorologicznej

Implementacja interfejsu Podmiot


w klasie DanePogodowe
Czy pamitasz nasz pierwsz prb implementacji klasy DanePogodowe, ktr
przeprowadzilimy na pocztku tego rozdziau? By moe bdziesz chcia nieco
odwiey sobie pami Teraz wanie nasta czas, aby do niej powrci
i troch j przeprojektowa majc na wzgldzie wymagania, jakie narzuca
nam wzorzec Obserwator
public class DanePogodowe implements Podmiot {
private ArrayList obserwatorzy;
private float temperatura;
private float wilgotno;
private float cinienie;

Tutaj dokonujemy implementacji interfejsu Subject.

public DanePogodowe() {
obserwatorzy = new ArrayList();
}

88

PAMITAJ: w prezentowanych
przykadach listingw nie umieszczamy
polece import ani package. Komplet
kodw rdowych poszczeglnych
przykadw znajdziesz na serwerze
FTP wydawnictwa HELION:
ftp://ftp.helion.pl/przyklady/wzorrg.zip

Klasa DanePogodowe implementuje


obecnie interfejs Podmiot.

em jest
ArrayList, ktrej zadani
Dodalimy zmienn typu
e tej zmiennej
eni
orz
tw
a
,
rw
ato
erw
przechowywanie listy obs
DanePogodowe.
struktora obiektw klasy
umiecilimy w definicji kon

Kiedy dany obserwator si rejestruje, dopisujemy


go po prostu na kocu listy.

public void zarejestrujObserwatora(Obserwator o) {


obserwatorzy.add(o);
Analogicznie, jeeli dany obserwator chce si wyrejestrowa,
}
po prostu usuwamy go z listy.
public void usuObserwatora(Obserwator o) {
A tutaj mamy co fajnego: to jest wanie miejsce,
int i = obserwatorzy.indexOf(o);
w ktrym mwimy obiektom obserwujcym
if (i >= 0) {
(obserwatorom), e zmieni si stan obiektu
obserwatorzy.remove(i);
obserwowanego. Poniewa wszystkie obiekty
}
obserwujce posiadaj interfejs Obserwator,
}
wiemy, e posiadaj take zaimplementowan
metod aktualizacja() i w zwizku z tym wiemy, jak
public void powiadomObserwatorw() {
moemy je powiadomi.
for (int i = 0; i < obserwatorzy.size(); i++) {
Obserwator Obs = (Obserwator)obserwatorzy.get(i);
Obs.aktualizacja(temperatura, wilgotno, cinienie);
}
iadamiali
}
bdziemy pow
Obserwatorw ych wartoci
iu now
po otrzyman
logicznej.
public void odczytyZmiana() {
stacji meteoro
ze
w
r
ia
m
po
powiadomObserwatorw();
}
public void ustawOdczyty(float temperatura, float wilgotno, float cinienie) {
this.temperatura = temperatura;
No dobra musimy si przyzna, e ze swojej strony chcieli
my
this.wilgotno = wilgotno;
sprzedawa kopi naszej wspaniaej aplikacji do obsugi stacji
this.cinienie = cinienie;
meteorologicznej razem z kadym egzemplarzem niniejszej
ksiki,
odczytyZmiana();
ale, niestety, nasz wydawca nie chcia si zgodzi na takie
rozwizanie.
}
Z tego zatem wzgldu, zamiast odczytywa wyniki pomiar
w z jakich
rzeczywistych urzdze na stacji meteo, bdziemy wykorz
ystywali
// tutaj zamie inne metody klasy DanePogodowe t metod do testow
ania naszych obiektw odpowiedzialnych
}
za poszczeglne tryby wywietlania. Jeeli chcesz, dla rozryw
ki
moesz napisa odpowiedni kod, ktry bdzie pobiera odpow
iednie
Rozdzia 2
informacje z jakiej strony sieci WWW.

Wzorzec Obserwator

A teraz pora na zbudowanie elementw wywietlajcych dane


Mamy ju nasz klas DanePogodowe zapit niemal na ostatni guzik, nadszed wic czas na stworzenie
elementw, ktre bd wywietlay odpowiednie informacje w poszczeglnych trybach pracy na ekranie.
Zleceniodawca, firma Pogodynka sp. z o.o., poprosia o przygotowanie trzech trybw wywietlania: Warunki
biece, Statystyka oraz Prognoza. Rzumy okiem na element odpowiedzialny za wywietlanie biecych
warunkw pogodowych; kiedy dokadnie si z nim zapoznasz i zrozumiesz jego zasady dziaania, powiniene
sprawdzi kody pozostaych dwch elementw, odpowiedzialnych za statystyk i prognozy (odpowiednie kody
rdowe znajdziesz na serwerze FTP wydawnictwa HELION: ftp://ftp.helion.pl/przyklady/wzorrg.zip). Szybko si
zorientujesz, e ich struktura jest bardzo zbliona.
Ta klasa, odpowiadajca za wywietlanie warunkw biecych,
posiada zaimplementowany interfejs Obserwator, dziki czemu
moe otrzymywa informacje o zmieniajcych si danych od
obiektu klasy DanePogodowe.

Ta klasa posiada rwnie zaimplementowany interfejs


WywietlElement, poniewa nasze API bdzie wymagao, aby
kady element odpowiedzialny za wywietlanie informacji na
ekranie posiada taki interfejs.

public class WarunkiBieceWywietl implements Obserwator, WywietlElement {


private float temperatura;
private float wilgotno;
Konstruktor obiektw klasy
private Podmiot DanePogodowe;
WarunkiBieceWywietl otrzymuje jako
argument wywoania obiekt DanePogodowe
public WarunkiBieceWywietl(Podmiot DanePogodowe) {
(czyli obiekt obserwowany, Podmiot),
this.DanePogodowe = DanePogodowe;
a nastpnie wykorzystuje go do
DanePogodowe.zarejestrujObserwatora(this);
zarejestrowania swojego obiektu jako
}
obserwatora.
public void aktualizacja(float temperatura, float wilgotno, float cinienie) {
this.temperatura = temperatura;
oda aktualizacja(),
Kiedy wywoywana jest met
this.wilgotno = wilgotno;
peratury otoczenia oraz
zachowujemy wartoci tem
wywietl();
).
woujemy metod wywietl(
wilgotnoci, a nastpnie wy
}
public void wywietl() {
System.out.println("Warunki biece " + temperatura
+ " stopni C oraz " + wilgotno + "% wilgotno");
}
}

Nie istniej

je po prostu
Metoda wywietl() powodu
ualnych
akt
j
dzie
bar
naj
nie
wywietle
otnoci.
wilg
i
odczytw temperatury

gupie pytania

P:

Czy metoda aktualizacja()


to najlepsze miejsce do
umieszczenia wywoania metody
realizujcej wywietlanie?

O:

W naszym prostym przykadzie


wywoywanie metody wywietl(), kiedy
nastpowaa aktualizacja danych, miao
sens. Nie zmienia to jednak faktu, e masz

racj, twierdzc, e istniej o wiele lepsze


sposoby wywietlania przychodzcych
danych. Przekonasz si o tym przy okazji
omawiania wzorca Model-WidokKontroler.

P:

Dlaczego odwoanie
do obiektu obserwowanego
(Podmiot) jest zapamitywane?
Przecie nie wyglda na to, aby

byo ono uywane gdziekolwiek


poza konstruktorem tej klasy?

O:

Prawda, aczkolwiek w przyszoci


moe zaistnie potrzeba usunicia
tego obiektu z listy zarejestrowanych
obserwatorw i wtedy posiadanie takiego
gotowego, istniejcego odwoania moe
okaza si bardzo uyteczne.

jeste tutaj

89

Testowanie stacji meteorologicznej

Wczamy zasilanie naszej stacji meteorologicznej


1

Po pierwsze, przygotujmy rodowisko testowe.


Nasz aplikacja do obsugi stacji meteorologicznej jest w zasadzie gotowa do pracy. Jedyne, czego jeszcze
bdziemy potrzebowa, to odrobina kodu, ktry poczy wszystkie stworzone do tej pory moduy w jedn,
zgrabn i sprawnie dziaajc cao. Poniej znajdziesz nasz pierwsz przymiark do tego zadania.
W nieco dalszej czci ksiki powrcimy jeszcze do tego zagadnienia i upewnimy si, e poszczeglne
elementy skadowe caej aplikacji mog by atwo do niej doczane za porednictwem odpowiedniego
pliku konfiguracyjnego. W chwili obecnej nasz kod wyglda nastpujco:
y
public class StacjaMeteo {

worzym
Najpierw ut
obiekt klasy
e.
DanePogodow

public static void main(String[] args) {


Jeeli nie chcesz
DanePogodowe danePogodowe = new DanePogodowe();
h
wyc
goto
ga
ci
przykadw z serwera
WarunkiBieceWywietl warunkiBieceWywietl =
FTP wydawnictwa
new WarunkiBieceWywietl(danePogodowe);
po
esz
mo
Helion,
StatystykaWywietl statystykaWywietl = new StatystykaWywietl(danePogodowe);
prostu wykomentowa
PrognozaWywietl prognozaWywietl = new PrognozaWywietl(danePogodowe);
te dwa wiersze
ram
prog
i
i uruchom
danePogodowe.ustawOdczyty(26.6, 65, 1013.1f);
Tworzymy trzy obiekty
bez nich.
danePogodowe.ustawOdczyty(27.7, 70, 997.0f);
odpowiedzialne za poszczeglne
danePogodowe.ustawOdczyty(25.5, 90, 997.0f);
tryby wywietlania
}
i przekazujemy im stworzony
}
Symulacja kolejnych wartoci
obiekt klasy DanePogodowe.
odczytw z czujnikw pogody.
2

90

Uruchom program i pozwl, aby zacza dziaa magia wzorca Obserwator.

Rozdzia 2

Wzorzec Obserwator

Zaostrz owek
Wanie przed chwil zadzwoni p. Janusz Monsun, prezes rady nadzorczej firmy Pogodynka sp. z o.o., i stwierdzi,
e sprzeda caego systemu nie bdzie moliwa, jeeli nie zostanie zaimplementowany nowy tryb wywietlania,
prezentujcy tzw. indeks ciepa. Poniej zaczamy definicj tego indeksu:
Indeks ciepa to wskanik, ktry czy ze sob wskazania temperatury i wilgotnoci powietrza i okrela rzeczywist
temperatur otoczenia (tzn. odczuwan temperatur). Aby obliczy warto indeksu ciepa, naley wzi warto
temperatury T*) oraz wilgotnoci wzgldnej RH, a nastpnie podstawi do poniszego wzoru:
indeksCiepa =
16.923 + 1.85212 * 10-1 * T + 5.37941 * RH - 1.00254 * 10-1 * T * RH +
9.41695 * 10-3 * T2 + 7.28898 * 10-3 * RH2 + 3.45372 * 10-4 * T2 * RH 8.14971 * 10-4 * T * RH2 + 1.02102 * 10-5 * T2 * RH2 - 3.8646 * 10-5 * T3 +
2.91583 * 10-5 * RH3 + 1.42721 * 10-6 * T3 * RH + 1.97483 * 10-7 * T * RH3
- 2.18429 * 10-8 * T3 * RH2 + 8.43296 * 10-10 * T2 * RH3 - 4.81975 * 10-11 *
T3 * RH3

Sowem, nie pozostao Ci nic innego, jak tylko rozpocz wklepywanie!


Oczywicie, artowalimy! Nie martw si, nie bdziesz musia pracowicie przepisywa caego wzoru; wystarczy,
e stworzysz swj wasny plik IndeksCiepa.java i skopiujesz do niego gotow formu, ktr znajdziesz w pliku
IndeksCiepa.txt.
Plik IndeksCiepa.txt moesz odnale na serwerze FTP wydawnictwa Helion:
ftp://ftp.helion.pl/przyklady/wzorrg.zip

Jak dziaa ta magiczna formua? Aby si tego dowiedzie, powiniene zajrze do ksiki Meteorologia. Rusz gow!
(o ile kiedy takowa si ukae), zapyta kogo pracujcego w Instytucie Meteorologii i Gospodarki Wodnej lub
po prostu zapyta Wielkiego Googlea (http://www.google.pl).
Po wprowadzeniu odpowiednich zmian i uruchomieniu programu wyniki jego dziaania powinny wyglda nastpujco:

akie
ny, j uway a
a
i
m
a ani
z
z
o

Ot iniene dzia
pow ynikach
w w ramu.
g
pro

jeste tutaj

91

Pogawdki przy kominku obserwowany kontra obserwujcy


Pogawdki przy kominku
Temat dzisiejszej wieczornej pogawdki: Obserwowany (Podmiot)
oraz Obserwujcy (Obserwator) przekomarzaj si na
temat najlepszego sposobu przekazywania informacji
o zmianach stanu do obiektw obserwujcych.

Obiekt obserwowany
Ciesz si, e w kocu mamy okazj porozmawia
osobicie.

Niby tak, ale przecie robi to, co do mnie naley.


Zawsze mwi Wam, co w trawie piszczy
To, e nie wiem, kim tak naprawd jestecie,
nie oznacza wcale, e o Was nie dbam. A poza tym
wiem o Was jedn, najwaniejsz rzecz macie
zaimplementowany interfejs Obserwator.

Tak? Ciekawe, co?

Obiekt obserwujcy

Naprawd?? A ja mylaem, e Ty zupenie nie


dbasz o nas, Obserwatorw.

Tak, pewnie, ale to tylko malutka cz tego,


co posiadamy. Tak czy inaczej, z pewnoci
wiemy o Tobie znacznie wicej
Na przykad to, e zawsze przekazujesz
informacje o swoim stanie nam, Obserwatorom,
abymy wiedzieli, co si wewntrz Ciebie
dzieje. A to od czasu do czasu moe by nieco
irytujce

Przepraszam BARDZO. Wysyam powiadomienia


wraz z informacjami o moim stanie tak, abycie Wy,
leniwi obserwatorzy, wiedzieli, co tu si w kocu
dzieje!

No dobrze. myl, e to mogoby zadziaa. Musiabym


tylko bardziej otworzy si na Wasze zakusy i pozwoli
wszystkim Obserwatorom dosta si do rodka tak, abycie
mogli samodzielnie pobiera potrzebne Wam informacje
o stanie. Niemniej jednak, takie rozwizanie moe by
nieco niebezpieczne. Nie mog przecie pozwoli na to,
aby Obserwatorzy wchodzili na mj teren bez zaproszenia
i przegldali wszystko, co mam do zaoferowania.

92

OK, poczekaj moment i nie gorczkuj si tak;


po pierwsze, nie jestemy leniwi, mamy po
prostu bardzo wiele innych zada do wykonania
pomidzy tymi Twoimi jake-bardzo-wanymipowiadomieniami, panie Obserwowany; po
drugie, dlaczego nie pozwolisz nam po prostu
wej na Twj teren i wzi potrzebnych
informacji, zamiast wypycha je uparcie na si
wszystkim Obserwatorom?

Rozdzia 2

rozdzial_02_kor_II.indd 92

2005-06-29 09:49:40

Wzorzec Obserwator

Obiekt obserwowany

Tak, mgbym w zasadzie pozwoli Ci na pobieranie


mojego stanu. Ale czy takie rozwizanie nie bdzie dla
Ciebie mniej wygodne? Jeeli musiaby przychodzi
do mnie za kadym razem, kiedy bdziesz czego
potrzebowa, to moe si zdarzy, e aby otrzyma
niezbdne informacje, bdziesz zmuszony do
wykonywania wielokrotnych wywoa metod.
Z tej prostej przyczyny wol wysya Wam mj stan
dziki temu otrzymujecie to wszystko, co niezbdne,
w jednym, prostym powiadomieniu.

Obiekt obserwujcy
To dlaczego po prostu nie napiszesz jakiej
publicznie dostpnej metody pozwalajcej
na pobieranie danych i nie udostpnisz nam
jej, abymy sami mogli pobiera niezbdne
informacje o Twoim stanie?

Nie bd taki natarczywy! Istnieje tak wiele


rnych typw Obserwatorw, e z pewnoci
nie moesz zawsze przewidzie wszystkich
naszych potrzeb. Po prostu pozwl nam wej
na Twj teren i pobra potrzebne informacje
o Twoim stanie. W ten sposb, jeeli ktry
z nas bdzie potrzebowa tylko pewnej
niewielkiej czci informacji, nie bdzie
zmuszony do przyjmowania ich kompletu.
Dziki temu atwiej pniej bdzie dokonywa
modykacji. Powiedzmy, na przykad, e troch
si rozwiniesz i Twj stan bdzie posiada kilka
nowych informacji. Wtedy, hmmm... jeeli
korzystasz z metody pobierania danych, nie
bdziesz musia biega dookoa i modykowa
metody aktualizacja() kadego zarejestrowanego
Obserwatora. Wystarczy, e zmienisz si sam,
udostpniajc nowe metody, dajce dostp do
dodatkowych elementw Twojego stanu.

Hmmm, jak by na to nie patrze, faktycznie oba sposoby


maj swoje zalety. Zauwayem, e Java posiada
wbudowan obsug wzorca Obserwator, ktry pozwala
na przesyanie informacji zarwno w postaci wysyania,
jak i pobierania danych.
Och, naprawd? Myl zatem, e powinnimy
mu si przyjrze
wietnie by moe bd mia zatem okazj
zobaczy dobry przykad takiego rozwizania, ktry
pozwoli mi zmieni zdanie

Niemoliwe, czybymy jednak doszlimy do


jakiego porozumienia? Czyli jednak zawsze jest
jaka nadzieja?
jeste tutaj

rozdzial_02_kor_II.indd 93

93

2005-06-29 09:49:40

Java wbudowany wzorzec Obserwator

Java zastosowanie
wbudowanego wzorca Obserwator
Jak pamitasz, do tej pory tworzylimy swj kod, zgodny z wymogami wzorca
Obserwator. Warto jednak wspomnie, e jzyk Java posiada take wasn obsug
tego wzorca, wbudowan w kilka rnych API. Najbardziej ogln implementacj
jest interfejs Observer i klasa Observable (oba elementy zlokalizowane w pakiecie
java.util). Elementy te s dosy podobne do naszych interfejsw Obserwator
i Podmiot, ale ju gotowe, i praktycznie natychmiast udostpniaj Ci swoj dosy
rozbudowan funkcjonalno. Dziki temu pakietowi moesz skorzysta zarwno
z metody wysyania powiadomie przez obiekt obserwowany, jak i z metody
pobierania stanu obiektu obserwowanego przez obiekty obserwujce, co zreszt
postaramy si zademonstrowa.

Dziki wbudowanej
w jzyk Java obsudze tego
wzorca wszystko, co musisz zrobi,
to tylko rozszerzy klas Observable
i poinformowa j, kiedy ma
powiadamia swoich obserwatorw.
Ca reszt wykona za Ciebie
API.

Aby lepiej zrozumie interfejs java.util.Observer i klas java.util.Observable,


przeanalizuj przedstawiony poniej nowy, zorientowany obiektowo projekt naszej
stacji meteorologicznej:

wszystkie
vable ledzi
Klasa Obser
ya do nich
w
i
rwujce ys
obiekty obse
a.
powiadomieni
odpowiednie

Observable to klasa,
a nie interfejs, std
klasa DanePogodowe
jest rozszerzeniem klasy
Observable (dziedziczy
po klasie Observable).

Observable

o.
yglda znajom
To powinno w
nie taki sam
ad
k
, jest to do
ie
ic
yw
cz
ze
R
agramie klas!
poprzednim di
interfejs, jak w
Obiekty obserwujce

<<interface>>
Observer

addObserver()
deleteObserver()
notifyObservers()
setChanged()

update()

sub

jec

OglnyWywietl
update()
wywietl()

StatystykaWywietl
update()
wywietl()

Pominlimy tutaj
interfejs WywietlElement,
aczkolwiek nadal jest
on zaimplementowany
we wszystkich klasach
odpowiadajcych za
wywietlanie.

PrognozaWywietl
update()
wywietl()

PogodaDane
pobierzTemperatur()
pobierzWilgotno()
pobierzCinienie()

glda
nie wy
ie
To ju jomo! Ale n m
e
a
n
z
a
b
k
ta
nie w
uj si, tego
jm
e
z
r
p
o
cimy d
powr
nie

u
wowany, ktry obec
temat
Oto nasz obiekt obser
.
ble
va
ser
Ob

wa
nazy
moemy w zasadzie
wicej metod
ju
my
uje
eb
trz
po
e
Ni
a()
a(), usuObserwator
or
at
rw
zarejestrujObse
ne
isa
op

)
w(
r
wato
ani powiadomObser
zymy teraz z klasy
zic
ied
dz
ia
an
ow
ch
za
nadrzdnej.

94

(dawna
zmian w metodzie update()
Tutaj musimy wprowadzi par
w zasadzie
ale
w,
tor
eglnych obserwa
metoda aktualizacja()) u poszcz
rfejs,
inte
lny
wsp
n,
jede
y
Nadal mam
caa idea jest cigle ta sama
rwo
obse wany.
() wywoywan przez obiekt
ktry posiada metod update

Rozdzia 2

rozdzial_02_kor_II.indd 94

2005-06-29 09:49:40

Wzorzec Obserwator

Java jak funkcjonuje wbudowany wzorzec Obserwator


Wbudowane mechanizmy obsugi wzorca Obserwator dziaaj nieco inaczej ni implementacja, ktrej uywalimy
w pocztkowej wersji projektu stacji meteorologicznej. Najbardziej oczywist rnic stanowi fakt, e klasa
DanePogodowe (czyli nasz obiekt obserwowany) jest teraz rozszerzeniem klasy Observable i dziedziczy po niej
metody addObserver(), deleteObserver() oraz notifyObservers() (a oprcz tego jeszcze kilka innych). Poniej
dowiesz si, w jaki sposb moemy skorzysta w jzyku Java z wbudowanego mechanizmu obsugi wzorca Obserwator.

Aby dowolny obiekt zosta obserwatorem


Jak zwykle, musisz zaimplementowa interfejs Obserwatora (teraz jest to interfejs java.util.Observer),
a nastpnie wywoa metod addObserver() dla dowolnego, wybranego obiektu klasy Observable.
Analogicznie, aby usun dany obiekt z listy obserwatorw, musisz wywoa metod deleteObserver().

Aby wybrany obiekt klasy Observable wysya powiadomienia o zmianie stanu


Po pierwsze i najwaniejsze, dany obiekt musi da si obserwowa, czyli musi dziedziczy po klasie
nadrzdnej java.util.Observable. Jeeli ten warunek jest speniony, trzeba wykona jeszcze dwa kroki:
1

Musisz wywoa metod setChanged(), aby zasygnalizowa,


e zmieni si stan obiektu obserwowanego.
Nastpnie musisz wywoa jedn z dwch dostpnych metod
notifyObservers():
notifyObservers() lub notifyObservers(Object arg).

dowolnego
a na pobranie stanie
al
zw
po
a
sj
Ta wer
pnie zo
ch, ktry nast miania do
obiektu dany
da
ia
w
po
s
podcza
przekazany
ych obiektw
an
w
ro
st
je
re
wszystkich za
h.
yc
c
uj
rw
se
ob

Aby obserwator otrzymywa powiadomienia


Obserwator posiada metod update(), ale sygnatura tej metody jest
jednak nieco inna:

obiekt
danych

update(Observable o, Object arg)


Jako argument jest tutaj
przekazywany obiekt, ktry
wysa powiadomienie

Tutaj jako argument jest przekazywany obiekt danych, ktry


wczeniej zosta przekazany do metody notifyObservers(), lub te
warto null, jeeli obiekt danych nie zosta wczeniej okrelony.

Jeeli chcesz wysya dane do obserwatorw, moesz przekaza odpowiednie dane jako obiekt danych
do metody notifyObserver(arg). Jeeli nie, obserwator musi pobiera potrzebne dane z obiektu
(obserwowanego) klasy Observable, ktry zostaje do niego przekazany. Jak? Zmienimy teraz po raz
kolejny projekt naszej stacji meteorologicznej i wtedy przekonasz si sam.
jeste tutaj

rozdzial_02_kor_II.indd 95

95

2005-06-29 09:49:41

Za kulisami

Czekaj, zanim si za to
wemiemy, wyjanij, prosz, do
czego bdzie nam potrzebna metoda
setChanged()? Poprzednio jej nie
potrzebowalimy.

Metoda setChanged() jest wykorzystywana do


zasygnalizowania, e stan obiektu obserwowanego
zmieni si i wywoanie metody notifyObservers()
powinno przynie aktualizacj danych dla obserwatorw.
Jeeli metoda notifyObservers() zostanie wywoana
bez uprzedniego wywoania metody setChanged(),
obserwatorzy NIE ZOSTAN powiadomieni.
Rzumy teraz okiem za kulisy (czyli zajrzyjmy do kodu
rdowego klasy Observable) i zobaczmy, jak dziaa
metoda setChanged().

Za
kulisami
setChanged() {
changed = true
}

ment
Frag okodu
d
pseu
s
kla y vable.
r
Obse

notifyObservers(Object arg){
if (changed) {
dla kadego obserwatora na licie {
call update(this, arg)
}
changed = false
}
}

awia flag
Metoda setChanged() ust
da (true).
aw
pr

rto
changed na wa
) bdzie
Metoda notifyObservers(
wycznie
ia
ien
wysyaa powiadom
changed
ga
fla
j
nie
ze
wtedy, jeli wc
rto
zostanie ustawiona na wa
prawda (true).

Po rozesaniu powiadomie metoda


ponownie ustawia flag changed na
warto fasz (false).

notifyObservers(){
notifyObservers(null)
}

Dlaczego takie rozwizanie jest konieczne? Metoda setChanged() zostaa pomylana jako sposb na
zapewnienie wikszej elastycznoci w sposobie powiadamiania obserwatorw, sposb pozwalajcy na
wprowadzenie optymalizacji powiadomie. Przykadowo, zamy, e na naszej stacji meteorologicznej
znajduj si tak bardzo czue przyrzdy, e odczyty temperatury cigle oscyluj wok pewnej temperatury
bazowej z dokadnoci do kilku setnych czci stopnia. Taka sytuacja moe spowodowa, e obiekt klasy
DanePogodowe bdzie nieustannie wysya nowe powiadomienia. Zamiast do tego dopuci, lepiej bdzie
wysya powiadomienia wycznie wtedy, kiedy rnica temperatury pomidzy dwoma kolejnymi pomiarami
wyniesie, dajmy na to, co najmniej p stopnia (inaczej mwic, tylko w takiej sytuacji wywoana zostanie
metoda setChanged()).
By moe nie bdziesz zbyt czsto korzysta z opisanego przed chwil mechanizmu, niemniej jednak, jeeli ju
zaistnieje taka konieczno, warto pamita, e rozwizanie masz gotowe. Pamitaj rwnie, e jeeli chcesz,
aby powiadomienia w ogle dziaay, musisz najpierw wywoa metod setChanged(). Jeeli zdecydujesz si
na korzystanie z opisanego mechanizmu, warto rwnie wspomnie o metodach takich, jak clearChanged()
(ustawia ag changed na warto fasz (false)) czy hasChange() (zwraca aktualny stan agi changed).

96

Rozdzia 2

rozdzial_02_kor_II.indd 96

2005-06-29 09:49:41

Wzorzec Obserwator

Kolejna wersja kodu Stacji Meteo


zastosowanie wbudowanych mechanizmw Javy
do obsugi wzorca Obserwator
Po pierwsze, dopasujemy kod klasy DanePogodowe tak,
aby mona byo skorzysta z klasy java.util.Observable

Upewnij si, e importujemy waciw


klas i waciwy interfejs.

Nie musimy ju duej ledzi naszych


obserwatorw ani zarzdza procesami ich
rejestracji oraz usuwania z listy (tym zajmuje
si ju klasa nadrzdna), wic usunlimy
kod przeznaczony uprzednio do rejestracji,
usuwania i wysyania powiadomie do
obserwatorw.

2 Teraz dla klasy Observable


tworzymy now klas
podrzdn.

import java.util.Observable;
import java.util.Observer;
public class DanePogodowe extends Observable {
private float temperatura;
private float wilgotno;
private float cinienie;
public DanePogodowe() { }
public void odczytyZmiania() {
setChanged();
notifyObservers();*
}

Nasz konstruktor ju nie musi


tworzy osobnej struktury danych
przeznaczonej do przechowywania
danych obserwatorw.

* Zwr uwag, e nie wysyamy ju obiektu danych do metody


notifyObservers(). Oznacza to, e wanie korzystamy
z metody POBIERANIA stanu obiektu obserwowanego.

Zanim wywoamy metod notifyObservers(), musimy


wywoa metod setChanged(), ktra ustawi flag
wskazujc, e stan obiektu obserwowanego zmieni si.

public void ustawOdczyty(float temperatura, float wilgotno, float cinienie) {


this.temperatura = temperatura;
this.wilgotno = wilgotno;
this.cinienie = cinienie;
odczytyZmiana();
}
public float pobierzTemperatur() {
return temperatura;
}
public float pobierzWilgotno() {
return wilgotno;
}
public float pobierzCinienie() {
return cinienie;
}

Te metody nie s nowe, ale poniewa chcemy skorzysta


z metody pobierania, pomylelimy sobie, e przypomnimy
Ci o ich istnieniu. Obserwatorzy bd ich uywa do
pobierania informacji o stanie obiektu klasy DanePogodowe.

jeste tutaj

rozdzial_02_kor_II.indd 97

97

2005-06-29 09:49:41

Modyfikacja trybu warunki biece

A teraz przyszed czas na modyfikacj klasy WarunkiBieceWywietl

Ponownie upewnij si, e importujemy


waciw klas i waciwy interfejs.

Obecnie importujemy interfejs Observer z pakietu java.util

import java.util.Observable;
import java.util.Observer;
public class WarunkiBieceWywietl implements Observer, WywietlElement {
Observable observable;
Konstruktor naszej klasy pobiera
private float temperatura;
3 obecnie obiekt klasy Observable, a my
private float wilgotno;
wykorzystujemy to do wpisania obiektu
opisujcego warunki biece na list
public WarunkiBieceWywietl(Observable observable) {
obserwatorw.
this.observable = observable;
observable.addObserver(this);
}
Zmodyfikowalimy metod
4 update() tak,
aby moga
public void update(Observable obs, Object arg) {
pobiera jako argumenty
if (obs instanceof DanePogodowe) {
zarwno obiekt klasy Observable,
DanePogodowe danePogodowe = (DanePogodowe)obs;
jak i opcjonalny obiekt danych.
this.temperatura = danePogodowe.pobierzTemperatur();
this.wilgotno = danePogodowe. pobierzWilgotno();
wywietl();
}
}
public void wywietl() {
System.out.println("Warunki biece " + temperatura
+ "stopni C oraz " + wilgotno + v% wilgotno");
}
}

98

W przypadku metody update()


najpierw musimy przekona si,
e obiekt obserwowany jest typu
DanePogodowe, a nastpnie
moemy wykorzysta jego
metody suce do pobierania
danych do uzyskania wartoci
pomiarw temperatury otoczenia
i wilgotnoci.
Na zakoczenie wywoujemy
metod wywietl().

Rozdzia 2

rozdzial_02_kor_II.indd 98

2005-06-29 09:49:41

Wzorzec Obserwator

Magnesiki z kodem
wiczenia

Jak wida, definicja klasy PrognozaWywietl znajduje si w kompletnej rozsypce. Czy moesz
poukada poszczeglne fragmenty kodu w odpowiedniej kolejnoci tak, aby cao znw
moga poprawnie dziaa? A przy okazji, niektre z nawiasw klamrowych pospaday nam
przy okazji na ziemi, a s zdecydowanie za mae, aby podejmowa wysiek ich podnoszenia,
wic moesz swobodnie dopisa tyle nawiasw klamrowych, ile bdzie potrzeba!
le
vab
ser
b
O
l(
iet
yw
W
a
z
gno
wywietl();
Pro {
c
)
li
pub rvable
e
obs
observable.add
Observer(this)
;

if (observable instanceof DanePogodowe) {

implements
public class PrognozaWywietl
Observer, WywietlElement {

{
wywietl()
public void
()
tl
ie
w
dy wy
// kod meto

e();
e;
ieni
i
n
n

e
i
ini
erzC
ceC we.pobi

e
i
o
b
ogod
e =
ieni = daneP
n

i
C
e
tnie
ieni
osta ceCin

bie
private floa
t bieceCi
nienie = 10
private floa
10.1f;
t ostatnieCi
nienie;
DanePogodowe da
nePogodowe =
(DanePogodowe)
observable;

able,
vable observ
update(Obser
id
vo
ic
bl
pu
{
Object arg)

bservable;
import java.util.O
bserver;
l.O
ti
a.u
import jav

jeste tutaj

rozdzial_02_kor_II.indd 99

99

2005-06-29 09:49:41

Jazda testowa

Uruchamianie nowego kodu


Aby si upewni, e wszystko dziaa, jak naley,
sprbujmy uruchomi now wersj naszej aplikacji

Hmmm, czy zauwaye tutaj jak rnic? Nie? Spjrz zatem jeszcze raz
Zobaczysz, e o ile wyniki oblicze niczym si od siebie nie rni, o tyle
(i nieco tajemniczo) kolejno wywietlania poszczeglnych wierszy jest zupenie
inna. Dlaczego tak si stao? Pomyl przez chwil, zanim przeczytasz odpowied
poniej

Nigdy nie polegaj na oszacowaniu kolejnoci wykonywania


poszczeglnych powiadomie
Klasa java.util.Observable posiada zaimplementowan metod notifyObservers(),
w ktrej poszczeglni obserwatorzy s powiadamiani w zupenie innej kolejnoci,
ni to miao miejsce w naszej wasnej implementacji. Kto zatem ma racj? Ot
nikt; po prostu, my wybralimy inny sposb implementacji.
Problem mgby si jednak pojawi w sytuacji, kiedy kod programu zaleaby
w istotny sposb od okrelonej kolejnoci powiadomie. Dlaczego? Ano dlatego,
e jeeli musiaby zmieni implementacj klasy Observable i (lub) interfejsu
Observer, kolejno powiadomie mogaby si rwnie zmieni, a Twoja
aplikacja najzwyczajniej w wiecie zaczaby generowa nieprawidowe rezultaty.
Oczywicie, taka implementacja jest jak najbardziej daleka od tego, co okrelamy
mianem lunych powiza.

100

Rozdzia 2

rozdzial_02_kor_II.indd 100

2005-06-29 09:49:42

Wzorzec Obserwator
Czy
definicja klasy java.util.
Observable nie stanowi przypadkiem
pogwacenia jednej z naszych regu
projektowania zorientowanego obiektowo,
goszcej, e naley skupi si na tworzeniu
interfejsw, a nie na implementacji?

Ciemna strona klasy java.util.Observable


Tak, to bardzo dobre pytanie. Jak zauwaye, Observable jest klas, a nie interfejsem. Co gorsza,
klasa ta nawet nie posiada zaimplementowanego interfejsu. Niestety, tak si jednak zoyo, e
implementacja klasy java.util.Observable jest obciona szeregiem problemw, ktre znacznie
ograniczaj jej uyteczno i moliwoci zastosowania. Nie mwimy tutaj, e jest ona cakowicie
bezuyteczna, stwierdzamy jedynie, e posiada kilka powanych dziur i wybojw, na ktre po
prostu trzeba uwaa.

Observable jest klas


Dziki przedstawionym wczeniej reguom projektowania ju wiesz, e to nie jest dobre
rozwizanie, ale tak waciwie, jakie zagroenia to ze sob niesie?
Po pierwsze, poniewa Observable jest klas, to aby z niej skorzysta, musisz stworzy jej
klasy podrzdne. Oznacza to w praktyce, e nie moesz doda zachowa klasy Observable
do ju istniejcej klasy, ktra dziedziczy po innej klasie nadrzdnej. Taka cecha zdecydowanie
ogranicza moliwoci wielokrotnego wykorzystywania tej klasy (i czy przypadkiem nie dlatego
zdecydowalimy si na korzystanie z wzorcw projektowych?).
Po drugie, poniewa nie istnieje interfejs Observable, nie moesz nawet zbudowa swojej
wasnej implementacji, ktra bdzie dobrze wsppracowaa z wbudowanym API interfejsu
Observer jzyka Java. Nie masz rwnie moliwoci wymiany pakietu java.util na inny
(powiedzmy, na taki, ktry potra obsugiwa wielowtkowo).

Klasa Observable chroni swoje kluczowe metody


Jeeli przyjrzysz si API wzorca Observer, przekonasz si, e metoda setChanged() jest
chroniona. I co z tego? No c, oznacza to mniej wicej tyle, e nie moesz wywoa metody
setChanged() dopty, dopki nie dokonasz dziedziczenia z superklasy Observable. Oznacza to
rwnie, e nie moesz nawet stworzy obiektu klasy Observable i wyposay go w swoje wasne
obiekty, po prostu jeste skazany na dziedziczenie. Struktura klasy Observable stanowi zatem
pogwacenie rwnie drugiej reguy projektowania Przedkadaj kompozycj nad dziedziczenie.

Co zatem robi?
Klasa Observable moe, mimo wszystko, odpowiada na Twoje potrzeby, jeeli moesz
dziedziczy z klasy java.util.Observable. Z drugiej jednak strony, zawsze moesz zdecydowa
si na stworzenie swojej wasnej implementacji, tak jak pokazalimy na pocztku niniejszego
rozdziau. Niezalenie od tego, na jakie rozwizanie si zdecydujesz, znasz ju dobrze wzorzec
Obserwator i dziki temu masz dobre podstawy do pracy z dowolnym API, ktre go wykorzystuje.
jeste tutaj

rozdzial_02_kor_II.indd 101

101

2005-06-29 09:49:42

Wzorzec Obserwator i biblioteka swing

Inne miejsca w JDK, w ktrych moesz


znale wzorzec Obserwator
java.util.Observer oraz java.util.Observable nie s jedynymi miejscami w JDK (ang.
Java Development Kit), w ktrych moesz odnale implementacj wzorca Observer;
zarwno komponenty JavaBean, jak i Swing mog si pochwali swoimi wasnymi
implementacjami tego wzorca. Na tym etapie wiedzy, na jakim obecnie si znajdujesz,
moesz spokojnie pokusi si o samodzieln analiz wymienionych API;
ale teraz, mimo wszystko, szybko zaprezentujemy przykad zastosowania biblioteki Swing,
ot, tak po prostu, dla przyjemnoci.

, jak
Jeeli jeste ciekawy
ja
ac
nt
me
ple
im
da
wygl
r
to
wa
ser
Ob
ca
or
wz
eresuj
w JavaBeans, zaint
sem
fej
er
int
j
si blie
stener.
PropertyChangeLi

Tytuem wprowadzenia
Rzumy okiem na jeden z prostych elementw Swing API, JButton. Jeeli zajrzysz pod
mask klasy nadrzdnej w stosunku do JButton, czyli superklasy AbstractButton, zobaczysz,
e posiada ona wiele metod pozwalajcych na dodawanie i usuwanie metod obiektw
nasuchujcych (inaczej suchaczy). Wspomniane metody pozwalaj na dodawanie
i usuwanie obserwatorw lub, jak je nazywaj w pakiecie Swing, obiektw nasuchujcych
z listy obiektw, ktre nasuchuj rnego rodzaju zdarze mogcych nastpi w obiekcie
bdcym czci biblioteki Swing (obiekt nasuchiwany). Przykadowo, ActionListener pozwala
na nasuchiwanie dowolnego typu zdarze, jakie mog wystpi w zwizku z przyciskiem
(np. nacinicie przycisku). W Swing API znajdziesz wiele rnych rodzajw obiektw
nasuchujcych.

Maa aplikacja, ktra odmieni nasze ycie


No dobrze, nasza aplikacja jest cakiem prosta. Posiada ona jeden przycisk, na ktrym guruje
pytanie Czy powinienem to zrobi?; kiedy klikniesz ten przycisk, suchacze (obserwatorzy)
musz odpowiedzie na to pytanie w taki sposb, w jaki bd chcieli. Zaimplementujemy
dwa takie obiekty nasuchujce, nazywane AnioSuchacz oraz DiabeSuchacz. Poniej
przedstawiono zachowanie naszej aplikacji:
owany interfejs.

A oto nasz wyrafin

Czy powinienem
to zrobi?

i dziaania
A tutaj mamy wynik
ymamy po
rz
ot
ie
jak
programu,
cisku.
naciniciu tego przy

Diabelska odpowied

Anielska odpowied

102

Rozdzia 2

rozdzial_02_kor_II.indd 102

2005-06-29 09:49:42

Wzorzec Obserwator

A oto i sam kod


Nasza zmieniajca-ycie-na-lepsze aplikacja nie wymaga zbyt duej iloci kodu. Wszystko, co musimy zrobi, to
stworzy obiekt JButton, dooy go do obiektu JFrame, a nastpnie skonfigurowa nasze obiekty nasuchujce.
W przypadku obiektw nasuchujcych uyjemy klas wewntrznych (ang. inner classes), co w bibliotece Swing
jest dosy rozpowszechnion technik programowania. Jeeli nie masz dowiadczenia w programowaniu klas
wewntrznych lub nie znasz biblioteki Swing, powiniene zajrze do rozdziau Historia bardzo graficzna
ksiki Java. Rusz gow! Wydanie II.
import
import
import
import

java.awt.*;
java.awt.event.*;
javax.swing.*;
javax.swing.event.*;

public class PrzykadObserwatoraSwing {


JFrame frame;

bibliotek
wykorzystujca
Prosta aplikacja
ramk
ona na ekranie
Swing. Tworzy
cisk.
zy
pr
ej
ni
z
tr
n
i umieszcza wew

public static void main(String[] args) {


PrzykadObserwatoraSwing przykad = new PrzykadObserwatoraSwing ();
przykad.uruchom();
}
public void uruchom() {
frame = new JFrame();
JButton button = new JButton("Czy powinienem to zrobi?");
button.addActionListener(new AnioSuchacz());
button.addActionListener(new DiabeSuchacz());
frame.getContentPane().add(BorderLayout.CENTER, button);
// Parametry okienka
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(BorderLayout.CENTER, button);
frame.setSize(300,300);
frame.setVisible(true);
}

Powoduje, e zarwno anielski, jak


i diabelski obiekt staje si obiektem
nasuchujcym (obserwatorem)
zdarze zwizanych z przyciskiem.

Tutaj umiesz
czon
klasy obserw e zostay
at
zdefiniowan orw,
e jako klasy
wewntrzn
e (ale wcale
tak by nie
musi).

class AnioSuchacz implements ActionListener {


public void actionPerformed(ActionEvent event) {
System.out.println("Nie rb tego! Moesz pniej aowa!");
}
}

class DiabeSuchacz implements ActionListener {


public void actionPerformed(ActionEvent event) {
System.out.println("Tak! Zrb to!");
wanego
obserwo rzycisk),
u
t
k
}
ie
b
o
stan
icie p
ienia si
toda
o oczyw
}
Kiedy zm przypadku jest t oywana jest me
w
m
y
y
w
z
s
(w na
pdate()
metody u
zamiast
().
d
e
rform
actionPe
jeste tutaj

103

Twoja projektowa skrzynka narzdziowa

Twoja skrzynka narzdziowa


Witamy na kocu rozdziau 2. Moesz
teraz z czystym sumieniem doda do
swojej skrzynki narzdziowej kilka
nowych elementw

CELNE
SPOSTRZEENIA

Wzorzec Obserwator definiuje


pomidzy obiektami relacj jeden-do-wielu.

Obiekty obserwowane (obiekty


Podmiot) przesyaj powiadomienia
i aktualizacje do obiektw
obserwujcych przy uyciu jednego,
wsplnego interfejsu.

Obiekty obserwujce s
luno powizane z obiektem
obserwowanym, co oznacza, e obiekt
obserwowany wie o nich tylko tyle,
e posiadaj zaimplementowany
interfejs Obserwator.

Zgodnie z definicj wzorca


informacje o zmianach stanu obiektu
obserwowanego mog by wysyane
lub pobierane (metoda pobierania
jest uwaana za bardziej politycznie
poprawn).

Nie mona uzalenia poprawnego


funkcjonowania aplikacji od okrelonej
kolejnoci powiadamiania przesyanego
do obiektw obserwujcych.

Java posiada kilka rnych


implementacji wzorca obserwator,
wczajc w to implementacj klasy
oglnego przeznaczenia w pakiecie
java.util.Observable.

Naley zwraca baczn uwag na


ograniczenia zwizane z implementacj
klasy java.util.Observable.

Nie naley si obawia tworzenia


wasnych implementacji klasy
Observable.

Biblioteka Swing bardzo mocno


wykorzystuje implementacj
wzorca Obserwator; jest to cecha
charakterystyczna niemal wszystkich
pakietw GUI.

Wzorzec Obserwator jest


wykorzystywany w wielu innych
miejscach, jak np. JavaBeans czy RMI.

nia

a
programow
y
w
a
t
s
d
o
P
o
obiektoweg
jno
Abstrakcy
zacja
o w a n iaHermety

ogram
Reguy pr
go
o b ie k t o w e cji to,

Polimorfizm
ie
Dziedziczen

a
h e r m e ty z
Po d d a w a j
n ia .
zec o si z m ie
d d z ie d z ic
p o z y c j n a
m
o
k
j
a
d
P r z e d k a
js w,
n ie .
iu in te r fe
a tw o r z e n
n

si
j
u
tr
Skoncen
m e n ta c ji .
a n ie im p le
k t r y c h
r o je k ty, w e i,
p

y
z
r
o
tw
zan
S ta r a j si
n o p o w i
z e so b lu z ia u j n a si e b ie
s
ty
k
ie
b
o
odd
li w e , n ie
o il e to m o
.
w z a je m n ie

o w a n ia
e program

o b ie k t o w e

jnowsza regua
Oto Twoja na
. Pamitaj, e
projektowania
ne
orzystujce lu
struktury wyk
ej
zi
iele bard
zwizki s o w
si
twiej adaptuj
a
i
ne
cz
elasty
do zmian.

go

, dokonuje
algorytmw ymienne. lacj jedeny
n
zi
d
ro
e wobiektami re
definiuje uje, e staj siiondzy
Strategy
owrod definiuje pyom
p
danegnoy obiekt zmienia
i
i
cj
cj
ka
fi
za
y
rwyato
ala nosabm,ode kiedygwo yablgraorytmzoustaj o tym
ich hermetObsete
w
oz
p
g
ki sp
tra
ry te zalene
Wzorzec Sdo-wielelunwietaod kliekinetaje, kt
go obiekty
ne.
zastan, wszyst
ie
n
u
ktualizowa
tm
y
algor
swj
atycznie za
m
to
u
a
i
e
n
uywa powiadomio

Wzorc

Nowy wzorzec projektowy, ktry pozwala na powiadamianie


zbioru obiektw o zmianach stanu, wykorzystujcy lune zwizki
pomidzy poszczeglnymi obiektami. Nie omawialimy jeszcze
ostatniego typu wzorca Obserwator poczekajmy z tym jednak
do czasu, a przedstawimy wzorzec MVC!

104

Rozdzia 2

Wzorzec Obserwator
wiczenia

Reguy projektowania wyzwanie


Napisz, w jaki sposb wzorzec Obserwator wykorzystuje
poszczeglne reguy projektowania.

Regua projektowania
Dokonaj identyfikacji wszystkich zmiennych
elementw Twojej aplikacji, a nastpnie oddziel je od
elementw, ktre przez cay czas pozostaj stae.

Regua projektowania
Skoncentruj si na tworzeniu interfejsw,
a nie implementacji

Ten przypadek moe sprawi nieco problemw, zatem


wskazwka: zastanw si, w jaki sposb obiekty obRegua projektowania
Przedkadaj kompozycj nad dziedziczenie.

serwujce wsppracuj z obiektem obserwowanym.

jeste tutaj

rozdzial_02_kor_II.indd 105

105

2005-06-29 09:49:44

Rozwizania wicze

Zaostrz owek

Rozwizania

Opierajc si na pierwszej implementacji naszego systemu,


okrel, ktre z wymienionych zdarze s prawdziwe. (Zaznacz
wszystkie poprawne odpowiedzi).
A. Tworzymy poszczeglne implementacje,
a nie interfejsy.

D. Poszczeglne wywietlane elementy


nie posiadaj wsplnego interfejsu.

B. Dodanie nowego trybu wywietlania bdzie


kadorazowo wymuszao modyfikacj kodu
programu.

E. Nie dokonalimy hermetyzacji tych


elementw aplikacji, ktre si zmieniaj.

C.

Reguy
projektowania
wyzwanie

Nie mamy adnych moliwoci dodawania


(lub usuwania) wybranych trybw
wywietlania podczas dziaania programu.

F.

Naruszylimy hermetyzacj klasy


PogodaDane.

Elementami, ktre we wzorcu Obserwator podlegaj zmianom, s: stan


obiektu obserwowanego oraz ilo i rodzaj obiektw obserwujcych.

Regua projektowania
Dokonaj identyfikacji wszystkich zmiennych
elementw Twojej aplikacji, a nastpnie oddziel je
od elementw, ktre przez cay czas pozostaj stae.

Zgodnie z zaoeniami wzorca moesz modyfikowa obiekty, ktre s


zalene od stanu obiektu obserwowanego bez koniecznoci modyfikacji
samego obiektu obserwowanego. To jest to, co nazywamy planowaniem
z wyprzedzeniem!

Zarwno obiekt obserwowany Podmiot, jak i obiekty obserwujce


wykorzystuj interfejsy. Obiekt obserwowany ledzi wszystkie obiekty,

Regua projektowania

ktre maj zaimplementowany interfejs Obserwator, podczas gdy

Skoncentruj si na tworzeniu interfejsw,


a nie implementacji

obiekty obserwujce do rejestracji, usuwania z listy zarejestrowanych


obiektw oraz do otrzymywania powiadomie wykorzystuj interfejs
Podmiot. Jak ju zauwaylimy, takie rozwizanie pozwala na
utrzymanie zgrabnej, luno zwizanej struktury obiektw.

Wzorzec Obserwator wykorzystuje zasad kompozycji do tworzenia


dowolnej liczby obiektw obserwujcych powizanych z danym obiektem

Regua projektowania
Przedkadaj kompozycj nad dziedziczenie.

obserwowanym. Takie relacje nie s w aden sposb tworzone poprzez


mechanizm dziedziczenia s za to tworzone cakowicie poprzez
kompozycj i to w trakcie dziaania programu!

106

Rozdzia 2

rozdzial_02_kor_II.indd 106

2005-06-29 09:49:44

Wzorzec Obserwator

Magnesiki z kodem

Rozwizania

servable;
import java.util.Ob
server;
import java.util.Ob
implements
public class PrognozaWywietl
Observer, WywietlElement {

private floa
t bieceCi
nienie = 10
private floa
10.1f;
t ostatnieCi
nienie;
rvable
public PrognozaWywietl(Obse
observable) {
DanePogodowe
danePogodowe
=
(DanePogodowe)
observable;

observable.addO
bserver(this);
}
able
update(Observ
public void
{
Object arg)

observable,

if (observable instanceof PogodaDane) {

ostatnieCinienie = bieceCinienie;
bieceCinienie = pogodaDane.pobierzCinienie();
}
}

wywietl();

{
wywietl()
public void
()
dy wywietl
to
me
d
ko
//
}

jeste tutaj

rozdzial_02_kor_II.indd 107

107

2005-06-29 09:49:44

You might also like