načítání...
nákupní košík
Košík

je prázdný
a
b

E-kniha: Návrhové vzory v PHP - Marian Böhmer

Návrhové vzory v PHP

Elektronická kniha: Návrhové vzory v PHP
Autor:

Pracujete s PHP a potřebujete dát svému vývoji větší řád? Řešíte opakovaně podobné typy problémů? Hledáte možnosti, jak vyvíjet rychleji, efektivněji a s menším úsilím? ... (celý popis)


hodnoceni - 75.2%hodnoceni - 75.2%hodnoceni - 75.2%hodnoceni - 75.2%hodnoceni - 75.2% 84%   celkové hodnocení
5 hodnocení + 0 recenzí

Specifikace
Nakladatelství: Computer press
Dostupné formáty
ke stažení:
PDF
Upozornění: většina e-knih je zabezpečena proti tisku
Médium: e-book
Počet stran: 320
Rozměr: 23 cm
Úprava: ilustrace
Vydání: 1. vyd.
Spolupracovali: překlad Lukáš Krejčí
Jazyk: česky
Téma: návrhové vzory
ADOBE DRM: bez
ISBN: 978-80-251-3338-5
Ukázka: » zobrazit ukázku
Popis

Pracujete s PHP a potřebujete dát svému vývoji větší řád? Řešíte opakovaně podobné typy problémů? Hledáte možnosti, jak vyvíjet rychleji, efektivněji a s menším úsilím? Začleňte do své praxe použití návrhových vzorů a předežeňte konkurenci perfektními softwarovými produkty.

Zkušený autor vás provede 23 návrhovými vzory a u každého vás seznámí nejen s jeho klíčovými přednostmi, ale ukáže vám i ukázkovou implementaci a upozorní vás na skryté problémy. To vše na příkladech z praxe s řadou vlastních zkušeností, které v běžných příručkách nenajdete. Každému vzoru se věnuje samostatná kapitola vždy se stejnou strukturou, knihu tak můžete číst od začátku do konce, nebo ji použít jako katalog vzorů.

S knihou se mimo jiné naučíte:
* Správně přistoupit k návrhu softwaru
* K čemu jsou jednotlivé vzory vhodné
* Využít přednosti jazyka UML
* Opakovaně použít již vytvořený kód
* Zvolit vhodný vzor pro daný problém
* Jak každý ze vzorů implementovat


O autorovi:
Marian Böhmer vystudoval obor Komunikační a informační technologie na Akademii ozbrojených sil v Liptovském Mikuláši. Je zkušeným programátorem v PHP a autorem řady projektů založených na Zend Frameworku. V době vydání knihy působil jako vedoucí IT oddělení a garant IT projektů.

Předmětná hesla
Související tituly dle názvu:
Návrhové vzory v PHP Návrhové vzory v PHP
Böhmer Marian
Cena: 444 Kč
Návrhové vzory v PHP Návrhové vzory v PHP
Böhmer Marian
Cena: 222 Kč
Návrhové vzory Návrhové vzory
Pecinovský Rudolf
Cena: 347 Kč
PHP Okamžitě PHP Okamžitě
Hopkins Callum
Cena: 222 Kč
PHP 6 PHP 6
Nowicki Steven D., Lecky-Thomson Ed
Cena: 703 Kč
Recenze a komentáře k titulu
Zatím žádné recenze.


Ukázka / obsah
Přepis ukázky

Marian Böhmer

Návrhové vzory v PHP

Computer Press

Brno

2012


Návrhové vzory v PHP

Marian Böhmer

Překlad: Lukáš Krejčí

Obálka: Martin Sodomka

Odpovědný redaktor: Martin Herodek

Technický redaktor: Jiří Matoušek

Objednávky knih:

http://knihy.cpress.cz

www.albatrosmedia.cz

eshop@albatrosmedia.cz

bezplatná linka 800 555 513

ISBN 978-80-251-3338-5

Vydalo nakladatelství Computer Press v Brně roku 2012 ve společnosti Albatros Media a. s. se sídlem

Na Pankráci 30, Praha 4. Číslo publikace 15 935.

© Albatros Media a. s. Všechna práva vyhrazena. Žádná část této publikace nesmí být kopírována

a rozmnožována za účelem rozšiřování v jakékoli formě či jakýmkoli způsobem bez písemného

souhlasu vydavatele.

1. vydání


Obsah

3

Obsah

ÚVODEM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11

Struktura knihy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

Komu je kniha určena . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

Zpětná vazba od čtenářů . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

Errata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

ČÁST I

ÚVOD DO NÁVRHU SOFTWARU

KAPITOLA 1

ZÁKLADNÍ PRAVIDLA PŘI NÁVRHU SOFTWARU . . . . . . . . . . . . .17

Pravidla softwarového návrhu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

Zapouzdření údajů . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

Aktéři . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .22

Implementace procesů půjčování. . . . . . . . . . . . . . . . . . . . . . . . . .24 Ladění aplikace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

Znovupoužitelnost kódu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34

Rozměnit na drobné . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .36

Kompozice místo dědění . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .38

Volná vazba místo závislostí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .41 Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44


4

Obsah

ČÁST II

TVOŘIVÉ VZORY

KAPITOLA 2

NÁVRHOVÝ VZOR SINGLETON . . . . . . . . . . . . . . . . . . . . . . . . . . . .49

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

Skryté problémy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

Další využití . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

Variace návrhového vzoru Singleton . . . . . . . . . . . . . . . . . . . . . . .57

KAPITOLA 3

NÁVRHOVÝ VZOR FACTORY METHOD . . . . . . . . . . . . . . . . . . . . .61

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

Další využití . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

Statická Factory Method a Singleton . . . . . . . . . . . . . . . . . . . . . . .68

KAPITOLA 4

NÁVRHOVÝ VZOR ABSTRACT FACTORY . . . . . . . . . . . . . . . . . . . .71

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

Implementace tabulky HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . .75

Implementace tabulky pro příkazový řádek . . . . . . . . . . . . . . . . . .82

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

Další využití . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87


Obsah

5

KAPITOLA 5

NÁVRHOVÝ VZOR BUILDER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .89

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 KAPITOLA 6 NÁVRHOVÝ VZOR PROTOTYPE . . . . . . . . . . . . . . . . . . . . . . . . . . .99

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

Skryté problémy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107

ČÁST III

STRUKTURÁLNÍ VZORY

KAPITOLA 7

NÁVRHOVÝ VZOR COMPOSITE . . . . . . . . . . . . . . . . . . . . . . . . . .113

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

Odstranění listů . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .118

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 KAPITOLA 8 NÁVRHOVÝ VZOR ADAPTER . . . . . . . . . . . . . . . . . . . . . . . . . . . . .121

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130

Další využití . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131


6

Obsah

KAPITOLA 9

NÁVRHOVÝ VZOR BRIDGE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .133

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 KAPITOLA 10 NÁVRHOVÝ VZOR DECORATOR . . . . . . . . . . . . . . . . . . . . . . . . . .145

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

Další využití . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

Test existence metody . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .158

KAPITOLA 11

NÁVRHOVÝ VZOR PROXY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .159

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167

Další využití . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 KAPITOLA 12 NÁVRHOVÝ VZOR FACADE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .171

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178

Další využití . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179


Obsah

7

KAPITOLA 13

NÁVRHOVÝ VZOR FLYWEIGHT . . . . . . . . . . . . . . . . . . . . . . . . . . .181

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194

ČÁST IV

VZORY CHOVÁNÍ

KAPITOLA 14

NÁVRHOVÝ VZOR OBSERVER . . . . . . . . . . . . . . . . . . . . . . . . . . .197

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209

Další využití . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 KAPITOLA 15 NÁVRHOVÝ VZOR MEDIATOR . . . . . . . . . . . . . . . . . . . . . . . . . . . .211

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 KAPITOLA 16 NÁVRHOVÝ VZOR TEMPLATE METHOD . . . . . . . . . . . . . . . . . . .219

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227

Další využití . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227


8

Obsah

KAPITOLA 17

NÁVRHOVÝ VZOR COMMAND . . . . . . . . . . . . . . . . . . . . . . . . . . .231

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240

Další využití . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 KAPITOLA 18 NÁVRHOVÝ VZOR MEMENTO . . . . . . . . . . . . . . . . . . . . . . . . . . . .241

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 KAPITOLA 19 NÁVRHOVÝ VZOR VISITOR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .243

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 KAPITOLA 20 NÁVRHOVÝ VZOR ITERATOR . . . . . . . . . . . . . . . . . . . . . . . . . . . .255

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 KAPITOLA 21 NÁVRHOVÝ VZOR STATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .265

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282


Obsah

9

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283

Další využití . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284 KAPITOLA 22 NÁVRHOVÝ VZOR STRATEGY . . . . . . . . . . . . . . . . . . . . . . . . . . . .285

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286 KAPITOLA 23 NÁVRHOVÝ VZOR CHAIN OF RESPONSIBILITY . . . . . . . . . . . . .287

Problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287

Účel návrhového vzoru . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288

Implementace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296

Skryté problémy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 KAPITOLA 24 NÁVRHOVÝ VZOR INTERPRETER . . . . . . . . . . . . . . . . . . . . . . . . .299

Definice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299

Shrnutí . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299

ČÁST V

PŘÍLOHY

PŘÍLOHA A

JAZYK UML. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .303

PŘÍLOHA B

VKLÁDÁNÍ ZÁVISLOSTÍ A PŘEVRÁCENÉ ŘÍZENÍ . . . . . . . . . . . .307

PŘÍLOHA C

MODERNÍ APLIKAČNÍ ROZHRANÍ

S PLYNULÝMI ROZHRANÍMI . . . . . . . . . . . . . . . . . . . . . . . . . . . . .309

REJSTŘÍK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .315



Úvodem

11

Úvodem

Návrhové vzory nabízejí postupy řešení často se vyskytujících problémů při

návrhu softwaru. Často jsou považované za velmi komplikované,asociova

né s komplexními diagramy jazyka UML a obtížně pochopitelnýmiarchi

tekturami. Tato kniha vám ukáže, že návrhové vzory a jejich implementace

v jazyce PHP nejsou až tak komplikované, jak se mohou někomu jevit po

prvním přečtení jejich definice. Na praktických příkladech se seznámíte

s  různými návrhovými vzory, které vám pomohou při každodenní práci

a kvůli nimž už nebudete muset organizovat velká pracovní střetnutí nebo

vytvářet vícestranné diagramy. Pomocí návodů v této knize se pro vásnávr

hové vzory stanou nástrojem, který vám ulehčí a obohatí chvíle při vývoji

aplikací v jazyce PHP.

Jazyk PHP 5 přinesl množství novinek, například kompletně přepraco

vanou podporu pro XML nebo jednodušší použití webových služeb přes

protokol SOAP, který je automaticky podporovaný v jazyce PHP. Přístup

k různým typům databází lze nyní díky PHP 5.1 a PDO provádět přesjed

notné rozhraní.

Naproti tomu tato aplikační rozhraní sama o sobě zatím neumožňovalarea

lizovat profesionální aplikace. O to se postaral až Zend Engine 2 s kompletně

přepracovaným objektovým modelem, který nabízí viditelnost pro atributy

a metody, rozhraní, výjimky, ale i abstraktní a finální třídy. To vám,jakož

to vývojářům v jazyce PHP, umožňuje navrhovat softwarové architektury,

které nebudou v ničem zaostávat za architekturami vývojářů v jazyce Java.

Tato kniha vám ukáže, jak můžete při návrhu softwaru využít prvkyjazy

ka PHP 5.3 k tomu, aby váš software splňoval moderní standardy a bylo jej

možné bez problémů rozšířit v případě, že se změní požadavky na aplikaci.


12

Úvodem

Dále se seznámíte s pravidly, která byste měli dodržovat při návrhuaplikace. Kromě toho vám návrhové vzory nabízejí jazyk, pomocí něhož můžete

řešit problémy s ostatními kolegy vývojáři, aniž abyste museli každý detail

podrobně vysvětlovat.

Struktura knihy

Celá kniha je rozdělená do pěti částí a lze ji číst dvěma způsoby. Buď jibudete číst postupně, od začátku do konce, a přitom se naučíte krok za krokem

jednotlivé návrhové vzory, nebo ji použijete jako katalog, v němž sivyhledáte přesně ten návrhový vzor, jehož implementací se chce zabývat. Každý

návrhový vzor představuje jednu kapitolu. V některých kapitolách sesetkáte s odkazy na jiné návrhové vzory – můžete je však použít i nezávisle na

sobě. Jiné kapitoly naopak nemusí být rozepsané dopodrobna, a tozvláště v případě, že popisovaný návrhový vzor lze nahradit jiným návrhovým

vzorem, který řeší stejný problém.

V úvodní části (kapitola 1 – Základní pravidla při návrhu softwaru) si na

příkladu vyzkoušíte, jakým chybám byste se měli vyhnout při návrhuarchitektury softwaru. Vyvodí se z nich všeobecně platná pravidla, jež se stanou

základem návrhových vzorů probíraných v této knize.

Druhá část (kapitoly 2–6) pojednává o návrhových vzorech týkajících se

tvorby objektů.

V  třetí části knihy (kapitoly 7–13) se představí návrhové vzory, které se

zabývají kompozicí různých objektů. V této části se navíc seznámíte sestrategiemi, které umožňují rozšiřitelnost daných kompozic.

Čtvrtá část (kapitoly 14–24) se zabývá poslední skupinou klasickýchnávrhových vzorů. Tyto vzory řeší problémy, které se mohou často vyskytnout

při interakci různých objektů.

V poslední, páté části (Příloha) najdete krátký úvod do jazyka UML, díky

němuž nebudete mít problém pochopit diagramy jazyka UMLv jednotlivých kapitolách. Kromě toho v této části najdete i techniky nazývanévkládání závislostí (angl. Depencency Injection), které staví nafilozofii převráceného řízení (angl. Inversion of Control – IoC), a také se naučíte vytvářet

aplikační rozhraní s Fluent Interfaces.


Úvodem

13

Ve všech výpisech v knize budou vynechané počáteční a koncové značky

(<?php a ?>) a bude uvedený jen kód jazyka PHP. Pro označení názvůjednot

livých tříd, metod a atributů budeme používat anglické pojmy, což je způsob,

který doporučuji i pro vaše projekty, protože tyto pojmy se lépe hodí k nativním

názvům tříd a funkcí jazyka PHP.

Pro lepší přehlednost nebudou uváděné komentáře. U reálných projektů byste

však měli myslet alespoň na popis aplikačního rozhraní pomocí nástroje PHPDoc

(http://www.phpdoc.org).

Všechny příklady jsou napsané pro jazyk PHP ve verzi 5.3. Chcete-li je použít

se starší verzí jazyka PHP, musíte je patřičně upravit – vzdát se používáníjmen

ných prostorů a odstranit z výpisů klíčová slova namespace a use.

Komu je kniha určena

Tato kniha je určená vývojářům, kteří už mají zkušenosti s  programováním

v jazyce PHP. V ideálním případě se už při realizaci projektu střetli s objektově

orientovaným programováním (OOP) v jazyce PHP 4 nebo PHP 5, avšak žádné

hluboké znalosti OOP v jazyce PHP 5 nejsou podmínkou.

Pro vysvětlení a pochopení jednotlivých návrhových vzorů probíraných v této

knize nejsou vyžadované žádné hluboké znalosti jazyka UML (UnifiedModel

ing Language). Kromě krátkého úvodu do tohoto jazyka, který najdete v pří

loze, nabízí tato kniha diagramy, jejichž obsah pro vás bude srozumitelný i se

základy jazyka UML.

Kniha Návrhové vzory v  PHP je napsaná pro programátory, kteří chtějí při

vytváření profesionálních architektur využívat vlastnosti OOP. Jejím těžištěm

je přitom architektura softwaru. Věci, které v knize nebudou probírané, setýka

jí oblasti nízkoúrovňové logiky, jako je například přístup k souborům,analyzo

vání dokumentů XML nebo přístup k údajům v databázi pomocí jazyka SQL.

Máte-li málo zkušeností s  jazykem PHP, avšak pojem návrhové vzory vám je

známý z jiných programovacích jazyků, můžete se pomocí této knihy seznámit

s implementací různých vzorů, jejichž realizace uvedeným způsobem je možná

jen v jazyce PHP.


Ú v o d e m

14

Zpětná vazba od čtenářů

Nakladatelství a vydavatelství Computer Press, které pro vás tuto knihupřipravilo, stojí o zpětnou vazbu a bude na vaše podněty a dotazy reagovat. Můžete se

obrátit na následující adresy:

redakce PC literatury

Computer Press

Spielberk Office Centre

Holandská 3

639 00 Brno

nebo

sefredaktor.pc@cpress.cz

Computer Press neposkytuje rady ani jakýkoli servis pro aplikace třetích

stran. Pokud budete mít dotaz k programu, obraťte se prosím na jeho tvůrce. Errata

Přestože jsme udělali maximum pro to, abychom zajistili přesnost a správnost

obsahu, chybám se úplně vyhnout nedá. Pokud v některé z našich knih najdete

chybu, ať už chybu v textu nebo v kódu, budeme rádi, pokud nám ji nahlásíte.

Ostatní uživatele tak můžete ušetřit frustrace a pomoci nám zlepšit následující

vydání této knihy.

Veškerá existující errata zobrazíte na adrese http://knihy.cpress.cz/K1886 poklepnutí na odkaz Soubory ke stažení.


Úvodem

15

ČÁST I

Úvod do návrhu

softwaru



17

KAPITOLA 1

Základní pravidla

při návrhu softwaru

Máloco podléhá tak častým změnám jako právě software. Ve většině projektů se

na něj nakládají stále nové požadavky a stejně rychle odpadají požadavky dosud

implementované – nebo v lepším případě jsou často pozměněné. Jako softwarový

vývojář musíte jednotlivé komponenty své aplikace navrhnout takovýmzpůso

bem, abyste mohli relativně rychle a flexibilně reagovat na měnící sepožadav

ky. V této kapitole se dozvíte, jak lze vyvíjet flexibilní aplikace, a také to, že je

důležité zamyslet se nad návrhem aplikace ještě před vlastní implementací. Tím

se vyhnete situaci, kdy náhle stojíte před problémem, kdy musíte přepsat velké

části aplikace, aby bylo možné reagovat na změněné požadavky. Jestliže tomu

nezabráníte, může každý změněný požadavek na software znamenat zvýšené

náklady, čímž se prodlouží čas nutný k dokončení projektu nebo se do softwaru

nestihnou zapracovat všechny požadavky.

Na příkladu v této kapitole si osvojíte základy návrhu softwaru a naučíte se, jak

sestavit aplikaci skládající se z více tříd, jež splňují požadavky na rozšiřitelnost

a flexibilitu.

Na konci kapitoly se dozvíte, jak lze co nejrychleji najít vhodný návrhový vzor

pro řešení budoucích problémů. Vyzbrojeni těmito vědomostmi můžete použít

následující kapitoly jako encyklopedii, když narazíte v jednom ze svých projektů

na problémy, které budete chtít vyřešit pomocí návrhových vzorů.


Část I Úvod do návrhu softwaru

18

Protože hlavním cílem této knihy je blíže vás seznámit se správnouarchitekturou aplikací, výklad nebude zacházet až do detailů a nebude se věnovatperzistentnímu ukládání údajů nebo grafickému uživatelskému rozhraní. Místo toho

budeme klást důraz na rozhraní, která vám dané třídy nabízejí, a na to, jakjednotlivé třídy mezi sebou komunikují.

Pravidla softwarového návrhu

K objasnění základních pravidel softwarového návrhu využijete následující

příklad. Představte si, že byste měli implementovat aplikaci, pomocí níž bude

knihovna spravovat své publikace. Na konci této kapitoly budete mít za sebou

vývoj funkční aplikace, s níž bude možné tyto publikace půjčovat a každétakovéto půjčení přesně protokolovat. V  reálné knihovně bude správce chtít jistě

ukládat o každé publikaci více informací a půjčování nebude nefungovat přesně

tak, jako to bude uvedené zde, ale jako příklad probírané problematiky to stačí.

Pokud jste se už nějakým způsobem zabývali objektově orientovanýmprogramováním, jsou vám pojmy třída (angl. Class), objekt (angl. Object) a možná i rozhraní

(angl. Interface) docela dobře známé. Koncepce tříd představuje pokus přenést

věci z reálného světa, s nimiž má aplikace něco společné, do světa programování.

Každý typ publikace má samozřejmě jiné vlastnosti, ale určitým způsobem se

všechny vzájemně podobají, z čehož lze odvodit následující rozhraní:

namespace czk1886example;

interface Publication {

public function open();

public function close();

public function setPageNumber($page);

public function getPageNumber();

} Reprezentace libovolné knihy by potom mohla vypadat následovně:

namespace czk1886example;

class Book implements Publication {

protected $category;

protected $pageCount;

protected $pageNumber = 0;

protected $closed = true;


Kapitola 1 Základní pravidla při návrhu softwaru

19

public function __construct($category, $pageCount) {

$this->category = $category;

$this->pageCount = $pageCount;

}

public function open() {

$this->closed = false;

}

public function setPageNumber($page) {

if ($this->closed !== false ||$thisageCount < $page) {

return false;

}

$this->pageNumber = $page;

return true;

}

public function getPageNumber()

{

return $this->pageNumber;

}

public function close() {

$this->setPageNumber(0);

$this->closed = true;

}

public function __destruct() {

if (!$this->closed) {

$this->close();

}

}

// další metody pro čtení atributů

} Reprezentace knihy má čtyři atributy: kategorii, do níž náleží, počet stran,konkrétní stranu, na níž je právě otevřená, a příznak udávající, zda je otevřená nebo zavřená.

Zapouzdření údajů

Třídy a objekty vám umožňují omezit přístup k údajům, čehož byste mělivyužívat. Díky tomu totiž můžete změnit vnitřní strukturu třídy, aniž by se to dotklo

jiných tříd nebo metod, které dotyčnou třídu používají. Takové změny mohou

být kromě jiného způsobené i následujícími důvody:


Část I Úvod do návrhu softwaru

20

 Změnily se požadavky na aplikaci, přičemž je nutné změnit algoritmy.

Pokud se změny provedou v rámci jedné třídy, neovlivní to žádnou z tříd,

jež upravenou třídu volají.

 Implementované algoritmy jsou velmi pomalé, protože aplikaci používá stále větší počet uživatelů. Tyto algoritmy můžete přepsat, povedou-li

ke stejnému výsledku.

 Je zapotřebí změnit úložiště údajů. K tomu může dojít například v situaci,

když zjistíte, že aktuální úložiště je vzhledem k objemu údajů nevhodné,

a je tedy nutné použít místo souboru databázi.

Pro objasnění znovu využijeme příklad knihovny. Vzhledem k  tomu, že půjčování publikací není zadarmo, musí být někde uložená denní sazba pro jednu

publikaci. Je-li tato hodnota zpočátku stále stejná, může vás napadnout použít

globální proměnnou nebo nějaký podobný způsob konfigurace:

$dailyRate = 10; Co se ale stane, přijde-li požadavek, aby se denní sazba pro dětské knihy lišila od sazby pro knihy vědecké nebo aby celková částka závisela na délcevypůjčení. Tím by velmi vzrostl počet konfiguračních možností a  museli byste v příslušných místech své aplikace implementovat logiku, pomocí níž byste načítali správnou konfiguraci. Z těchto důvodů je lepší zapouzdřit přístup k denní sazbě hned od začátku.Protože se předpokládá, že výška této sumy se bude lišit v závislosti na vypůjčené publikaci, představuje rozhraní Publication dobré místo pro tuto logiku. Toto rozhraní totiž implementují všechny publikace (knihy, časopisy apod.).Rozšiřte tedy toto rozhraní o jednu metodu a tu pak implementujete v příslušnýchtřídách. Příklad metody pro třídu Book by mohl vypadat následovně:

namespace czk1886example;

class Book implements Publication {

// ... atributy a metody

public function getDailyRate() {

return 10;

}

}


Kapitola 1 Základní pravidla při návrhu softwaru

21

Má-li být pro jiný typ knihy účtovaná jiná denní sazba, pak stačí jen přepsat tuto

metodu a nový požadavek máte implementovaný. Tím jste se seznámili s prvním

pravidlem návrhu softwaru u objektově orientované architektury:

PRAVIDLO

Přístup k údajům vždy v rámci třídy zapouzdřete a poskytněte metody, pomocí

nichž lze dané údaje získat. Stejně jednoduchá je implementace požadavku, aby denní sazba byla nižšív příadě vypůjčení knihy na déle než dva týdny. V tomto případě stačí také změnit jen jednu metodu:

namespace czk1886example;

class Book implements Publication {

// ... atributy a metody

public function getDailyRate($days = 1) {

if ($days >= 14) {

return 7.50;

}

return 10;

}

} S tím také samozřejmě souvisí úprava tříd, jež volají metodu getDailyRate(), protože tato metoda musí od nynějška předávat počet dní. Této dodatečné změně se můžete vyhnout, pokud jste se při návrhu rozhraní pokusili stanovit, jaké údaje by byly eventuálně potřebné při výpočtu denní sazby. Nikdy všaknebude možné zohlednit všechny budoucí požadavky hned při první implementaci rozhraní. V takovém případě byste museli metodě předávat všechny dostupné údaje, čímž byste rozbili zapouzdření údajů. Pokuste se najít zlatou střední cestu a metodu navrhnout tak, aby byla v budoucnosti jednoduše rozšiřitelná – jak jsme si to ukázali v tomto příkladu. Tím jste se naučili už druhé pravidloobjektově orientovaného návrhu softwaru:

PRAVIDLO

Svá rozhraní navrhujte tak, aby je bylo možné později rozšířit.

PRAVIDLO

Přístup k údajům vždy v rámci třídy zapouzdřete a poskytněte metody, pomocí

nichž lze dané údaje získat.

PRAVIDLO

Svá rozhraní navrhujte tak, aby je bylo možné později rozšířit.


Část I Úvod do návrhu softwaru

22

Na začátku návrhu softwaru provedete vždy stejné kroky: musíte se zamyslet

nad spravovanými údaji a nad tím, jak lze tyto údaje zahrnout do entit. Z toho

pak vyplynou jednotlivé třídy a metody.

Aktéři

V  příkladu knihovny se nacházejí následující aktéři, kteří musí být částí vaší

aplikace:

 jednotlivé knihy, které jsou částí knihovny a lze je půjčovat,

 členové knihovny, kteří si knihy půjčují,

 samotná knihovna, která spravuje jednotlivé publikace a stará seo půjčování.

Z těchto představitelů můžete hned odvodit potřebné třídy a rozhraní. Pro knihy

jste to už provedli, zůstávají už jen členové a  knihovna. Implementujte proto

třídu Member, která bude reprezentovat jednoho člena knihovny:

namespace czk1886example;

class Member {

protected $id;

protected $name;

public function __construct($id, $name) {

$this->id = $id;

$this->name = $name;

}

public function getId() {

return $this->id;

}

public function getName() {

return $this->name;

}

} Daný člen se skládá z jedinečného identifikátoru, jímž se v systémuidentifikuje, a ze svého jména, což pro jednoduchou demonstraci úplně stačí. Informace, které jsou přiřazené členovi, se předají prostřednictvím konstruktoru a uloží se do atributů objektu. Přístup k těmto údajům je možný pomocí metod getId() a getName().


Kapitola 1 Základní pravidla při návrhu softwaru

23

Po vytvoření tříd pro členy a knihy nastal čas věnovat se samotné knihovně,kterou reprezentuje třída Library:

namespace czk1886example;

class Library {

protected $library = array();

public function addToLibrary($id, Publication $p) {

$this->library[$id] = $p;

}

public function rentPublication(Publication $p, Member $m) {

}

public function returnPublication(Publication $p) {

}

} Knihovna má jeden atribut, do něhož se ukládají všechny publikace určené k vypůjčení, a také tři metody:

 Metoda addToLibrary() se používá k přiřazení nové publikace doknihovny. Tato publikace se jednoduše uloží do pole $library.

 Pomocí metody rentPublication() si může člen knihovny vypůjčitkonkrétní publikaci. Tuto metodu jste zatím neimplementovali, neboť nejdříve

je nutné definovat, v jaké formě se budou údaje ukládat.

 Pro vrácení publikace se používá metoda returnPublication(). V tomto

případě není nutné předat objekt člena, který publikaci vrací. Koneckonců

knihovna přece musí vědět, kdo měl danou publikaci vypůjčenou.

V následujících krocích budete deklarovat metody naplněné skutečnou logikou.

Metody rentPublication() a returnPublication() mají vždy něco společné

s vypůjčením publikace. Buď proces vypůjčení začal, nebo byl vrácenímpublikace zpět do knihovny ukončený.

Tohoto procesu se vždy účastní dva aktéři: publikace, která má být vypůjčena,

a osoba, která si ji vypůjčila. Dále jsou důležité časové údaje, kdy byla publikace

vypůjčená a také kdy byla vrácená, aby tak bylo možné vypočítat cenu zavypůjčení. Ve  skutečné knihovně to většinou funguje jinak, ale jako příklad postačí i  tato varianta. Podle pravidel zapouzdřování, která jste se právě naučili, se

pokuste dostat tyto informace do jedné třídy.


Část I Úvod do návrhu softwaru

24

Implementace procesů půjčování

Nová třída RentalAction musí obsahovat následující informace:

 osoba, která si publikaci půjčuje,

 publikace, která se půjčuje,

 datum, kdy byla publikace vypůjčena,

 datum, kdy byla publikace vrácena a proces ukončen.

Implementace této třídy může vypadat následovně:

namespace czk1886example;

class RentalAction {

protected $publication;

protected $member;

protected $rentDate;

protected $returnDate = null;

function __construct(Publication $p, Member $m, $date = null) {

$this->publication = $p;

$this->member = $m;

// v případě neuvedení data použít aktuální

if (null === $date) {

$date = date('Y-m-d H:i:s');

}

$this->rentDate = $date;

}

public function getPublication() {

return $this->publication;

}

public function getMember() {

return $this->member;

}

public function getRentDate() {

return $this->rentDate;

}

public function getReturnDate() {

return $this->returnDate;


Kapitola 1 Základní pravidla při návrhu softwaru

25

}

} Konstruktoru třídy musíte při vytvoření nového procesu předat jakoparametry publikaci, která má být vypůjčena, a dále osobu, která si ji půjčuje.Volitelně můžete uvést datum a čas, kdy byla daná publikace vyzvednuta. V případě neuvedení data se použije aktuální datum. Tyto hodnoty se uloží v příslušných atributech třídy. Dále se ve třídě nacházejí čtyři metody pro čtení atributů, které vám umožňují přistupovat k atributům třídy. Pokud si nyní přijde nějaký člen vaší knihovny vypůjčit určitou publikaci, můžete vytvořit odpovídající proces vypůjčení takto:

use czk1886exampleBook;

use czk1886exampleMember;

use czk1886exampleRentalAction;

$book = new Book('PC', 100);

$mabo = new Member(1, 'Marian Böhmer');

$rentalAction = new RentalAction(

$book, $mabo, '2011-08-22 16:00:00'

); V této chvíli je sice možné knihu vypůjčit, avšak zatím není možnézaznamenat, že už byla i vrácena. Pro tento účel jste si v této třídě už předemrezervovali atribut $returnDate. K jeho nastavení je nutné vložit do třídy RentalAction následující metodu:

namespace czk1886example;

class RentalAction {

// ... atributy a metody třídy

public function markPublicationReturned($date = null) {

// v případě neuvedení data použít aktuální

if (null === $date) {

$date = date('Y-m-d H:i:s');

}

$this->returnDate = $date;

}

} Bude-li publikace přinesena zpět do knihovny, pak pro uložení této informace do objektu stačí zavolat příslušnou metodu:


Část I Úvod do návrhu softwaru

26

$rentalAction->markPublicationReturned('2011-08-30 13:00:00'); Výsledek této operace je zobrazený na obrázku 1.1. Obrázek 1.1: Proces vypůjčení knihy z knihovny Pokud si chcete ověřit, zda byla kniha vrácena a tím daný proces ukončen,můžete k tomu využít hodnotu, kterou vrací metoda getReturnDate():

if (null !== $rentalAction->getReturnDate()) {

print 'Publikace byla vrácená';

} Tento kód se však neimplementuje jednoduše, a proto je vhodné zapouzdřit jej do další metody:

namespace czk1886example;

class RentalAction {

// ... atributy a metody třídy

public function isReturned() {

return null !== $this->returnDate;

}

}


Kapitola 1 Základní pravidla při návrhu softwaru

27

Tuto metodu můžete nyní využít ke zjištění, zda už byla publikace vrácena:

if ($rentalAction->isReturned()) {

print 'Publikace byla vrácená';

} Tím jste se naučili další pravidlo vývoje softwaru:

PRAVIDLO

V metodách tříd nezapouzdřujte jen údaje, ale také algoritmy, díky čemuž budou

komplexní operace implementované centrálně na jednom místě. Zavedení metody isReturned() vám v budoucnosti umožní na základěpodmínky určit, zda už byl proces vypůjčení ukončen a kniha vrácena zpět do knihovny. Pomocí nové třídy RentalAction je možné implementovat chybějící metody ve třídě Library. Nejdříve je nutné vložit do uvedené třídy nový atribut$rentalActions, v němž budou v podobě objektů uložené jednotlivé procesy vypůjčení. Nejjednodušším datovým typem použitelným k tomuto účelu je pole. Následující implementace metody pro vypůjčení publikace musí splňovatnásledující kritéria:

 otestovat, zda je požadovaná publikace součástí knihovny,

 otestovat, zda je požadovaná publikace aktuálně vypůjčená (v takovémpříadě ji nelze znovu vypůjčit),

 pomocí nové instance třídy RentalAction vytvořit nový proces vypůjčení. Implementace metody rentPublication() může vypadat následovně:

namespace czk1886example;

class Library {

protected $rentalActions = array();

// ... atributy a metody třídy

public function rentPublication(Publication $p, Member $m) {

$publicationId = array_search($p, $this->library);

if (false === $publicationId) {

throw new UnknownPublicationException();

}

if (!$this->isPublicationAvailable($p)) {

throw new PublicationNotAvailableException();

PRAVIDLO

V metodách tříd nezapouzdřujte jen údaje, ale také algoritmy, díky čemuž budou

komplexní operace implementované centrálně na jednom místě.


Část I Úvod do návrhu softwaru

28

}

$rentalAction = new RentalAction($p, $m);

$this->rentalActions[] = $rentalAction;

return $rentalAction;

}

} Pomocí funkce array_search() jazyka PHP můžete zjistit, zda se publikace nachází v nabídce knihovny. Vrátí-li hodnotu false, pak signalizuje chybuvyvoláním výjimky. Test, zda je daná publikace právě vypůjčená, je trochukomplikovanější, a proto je jeho logika přesunuta do další metody. Díky tomu mohou tuto logiku použít i  jiné metody třídy. Tímto způsobem opět zapouzdřujete určitý algoritmus do jedné metody. Konkrétní implementace této metody budeprobrána později. V případě, že publikace není vypůjčená, vytvoří se nová instance třídy RentalAction, které předáte půjčovanou publikaci a člena, který si jipůjčuje. Tuto instanci potom uložíte do k tomu určeného atributu, kde jsouuložené i všechny ostatní procesy vypůjčení. Metoda rentPublication() vrací objekt RentalAction. Vrácení tohoto objektu sice není v současnosti pro knihovnudůležité, protože neobsahuje žádné další informace než ty, které už obdržela, avšak v budoucnosti může objekt RentalAction obsahovat i další informace, například číslo objednávky, které budete chtít poskytnout aplikaci. Ještě před tím, než začnete ve vypůjčené publikaci listovat, je nutné podívat se na implementaci pomocné metody isPublicationAvailable(). Pro  zjištění, zda je daná publikace právě vypůjčená, stačí jen otestovat, zda atribut$rentalActions obsahuje proces vypůjčení pro hledanou publikaci, který ještě nebyl ukončen. K tomuto účelu vám dobře poslouží metody pro čtení atributů třídy RentalAction:

public function isPublicationAvailable(Publication $p) {

foreach ($this->rentalActions as $rentalAction) {

if ($rentalAction->getPublication() !== $p) {

continue;

}

if ($rentalAction->isReturned()) {

continue;

}

return false;

}

return true;

}


Kapitola 1 Základní pravidla při návrhu softwaru

29

Ve funkci isPublicationAvailable() probíhá iterace přes všechny prvky v poli

$rentalActions (všechny procesy vypůjčení). Pokud aktuální proces nepatří

hledané publikaci nebo už je ukončený, pokračuje se s další iterací. Pokud daný

proces náleží k hledané publikaci a ještě není ukončen, nemůže být danápublikace znovu vypůjčena, což se signalizuje vrácením hodnoty false.Neexistuje-li pro hledanou publikaci žádný proces, který ještě nebyl ukončen, vrátí se

hodnota true.

V  tomto okamžiku lze třídu Library použít k  půjčování publikací a  navíc je

zaručené, že jedna publikace může být vypůjčená jen jednou, jak to ukazuje

následující příklad:

use czk1886exampleLibrary;

use czk1886exampleBook;

use czk1886exampleMember;

$library = new Library();

$book = new Book('PC', 100);

$mabo = new Member(1, 'Marian Böhmer');

$luigi = new Member(2, 'Luigi Valentino');

$library->addToLibrary('pc1', $book);

$library->rentPublication($book, $mabo);

$library->rentPublication($book, $luigi); Po jeho provedení reaguje knihovna následující výjimkou:

Fatal error: Uncaught exception 'czk1886example

PublicationNotAvailableException' in ch01Library.php:24 Tuto výjimku můžete ve frontendu své aplikace změnit na chybové hlášení. Aby bylo možné i  vrácení vypůjčených publikací, musíte dále implementovat metodu returnPublication(). Tato metoda musí najít aktuální procesvypůjčení, který náleží k dané publikaci, a označit jej jako ukončený. Kód této metody se podobá tomu v metodě isPublicationAvailable(). I v tomto případěprocházíme přes všechny procesy vypůjčení, dokud nenajdeme proces prohledanou publikaci, který ještě nebyl ukončen. Tento proces potom označíme pomocí metody markPublicationReturned() jako ukončený. Kompletní implementace vypadá takto:

namespace czk1886example;

class Library {


Část I Úvod do návrhu softwaru

30

// ... atributy a metody třídy

public function returnPublication(Publication $p) {

foreach ($this->rentalActions as $rentalAction) {

if ($rentalAction->getPublication() !== $p) {

continue;

}

if ($rentalAction->isReturned()) {

continue;

}

$rentalAction->markPublicationReturned();

return true;

}

return false;

}

} V tomto okamžiku mohou být vypůjčené publikace znovu vrácenya připraveny na své další vypůjčení:

use czk1886exampleLibrary;

use czk1886exampleBook;

use czk1886exampleMember;

$library = new Library();

$book = new Book('PC', 100);

$mabo = new Member(1, 'Marian Böhmer');

$luigi = new Member(2, 'Luigi Valentino');

$library->addToLibrary('pc1', $book);

$library->rentPublication($book, $mabo);

$library->returnPublication($book);

$library->rentPublication($book, $luigi); Při provedení tohoto kódu nedošlo k  vyvolání žádné výjimky. Místo toho se vytvořily dva procesy vypůjčení, z nichž jeden byl i ukončený. U této implementace vás možná napadne, proč není proces po jeho ukončení z  pole vymazán? Jednoduše proto, že byste v  takovém případě ztratili historii procesů vypůjčení. Představte si, že by chtěl správce knihovny zjistit, kterépublikace se nejvíce půjčují nebo kdo je nejaktivnějším členem knihovny. Pomocí procesů uložených v poli $rentalActions lze tyto údaje snadno poskytnout. Je nutné si uvědomit, že v tomto příkladu nešlo o uchovávání údajů ani o jeho výkonnost, ale o vytvoření architektury aplikace. Místo pole s objekty typuRen>


Kapitola 1 Základní pravidla při návrhu softwaru

31

talAction byste v reálné aplikaci použili pro jejich uložení databázovou tabulku.

Databázové systémy už nabízejí nástroje, jak lokalizovat záznam k aktuálnímu

procesu vypůjčení konkrétní publikace.

Ladění aplikace

V této chvíli máte za sebou základy aplikace a jste schopni půjčovat publikace

a přijímat je zpět. V této podkapitole si na příkladu části aplikace ukážeme, jaká

další pravidla návrhu softwaru byste měli ve svých aplikacích zohlednit.

Třebaže funkce pro ladění (angl. debugging) aplikací v  jazyce PHP lze zlepšit

pomocí externích nástrojů, skoro každý vývojář v jazyce PHP využívá k výpisu

nezbytných informací při tomto kroku příkaz print nebo echo. Tyto příkazy se

během vývoje jednoduše vloží do zdrojového kódu a před tím, než se aplikace

nasadí do provozu, se zase odstraní. V rámci této části budete takovýto ladicí

kód postupně, kroku za krokem vylepšovat, při čemž se seznámíte s  různými

pravidly, která byste měli zohlednit i v dalších softwarových projektech.

Při dalším vývoji softwaru knihovny můžete do zdrojového kódu následujícím

způsobem vložit hlášení používané při ladění:

namespace czk1886example;

use czk1886exampleRentalAction;

class Library {

protected $library = array();

protected $rentalActions = array();

public function addToLibrary($id, Publication $p) {

$this->library[$id] = $p;

print 'Nová publikace v knihovně: '

. $p->getCategory() . "";

}

public function rentPublication(Publication $p, Member $m) {

$publicationId = array_search($p, $this->library);

if (false === $publicationId) {

throw new UnknownPublicationException();

}

if (!$this->isPublicationAvailable($p)) {

throw new PublicationNotAvailableException();

}


Část I Úvod do návrhu softwaru

32

$rentalAction = new RentalAction($p, $m);

$this->rentalActions[] = $rentalAction;

print $m->getName() . ' si vypůjčil publikaci: '

. $p->getCategory() . "";

return $rentalAction;

}

public function returnPublication(Publication $p) {

foreach ($this->rentalActions as $rentalAction) {

if ($rentalAction->getPublication() !== $p) {

continue;

}

if ($rentalAction->isReturned()) {

continue;

}

$rentalAction->markPublicationReturned();

print $rentalAction->getMember()->getName()

. ' vrátil publikaci: '

. $p->getCategory() . "";

return true;

}

return false;

}

// ... ostatní metody

} Pokud nyní znovu zavoláte příkazy z předchozího testovacího skriptus pozměněnou třídou Library, můžete přesně sledovat, kdy se která metoda volá:

Nová publikace v knihovně: PC

Marian Böhmer si vypůjčil publikaci: PC

Marian Böhmer vrátil publikaci: PC

Luigi Valentino si vypůjčil publikaci: PC V závislosti na tom, jakou část aplikace chcete ladit, se bude měnit i množství ladicích informací. Před přesunem aplikace na produkční server jednoduše tyto řádky kódu vymažete. Co se ale stane, pokud objevíte problém, který se vyskytuje jen v produkčním prostředí, protože souvisí například s množstvím paralelních dotazů na aplikaci? Tato hlášení nemůžete jednoduše zobrazit koncovému uživateli. V takovémpříadě používá většina vývojářů protokolovací soubor, do něhož přesměrujíveškerá hlášení. Často je tedy ladicí kód rozšířený o příkazy if/else nebo switch,


Kapitola 1 Základní pravidla při návrhu softwaru

33

pomocí nichž lze přepínat mezi laděním v produkčním nebo vývojovémprostředí. V případě knihovny by to vypadalo následovně:

namespace czk1886example;

class Library {

protected $library = array();

protected $rentalActions = array();

public function addToLibrary($id, Publication $p) {

$this->library[$id] = $p;

switch(DEBUG_MODE) {

case 'echo':

print 'Nová publikace v knihovně: '

. $p->getCategory() . "";

break;

case 'log':

error_log('Nová publikace v knihovně: '

. $p->getCategory() . "",

3, './library.log');

break;

}

}

public function rentPublication(Publication $p, Member $m) {

$publicationId = array_search($p, $this->library);

if (false === $publicationId) {

throw new UnknownPublicationException();

}

if (!$this->isPublicationAvailable($p)) {

throw new PublicationNotAvailableException();

}

$rentalAction = new RentalAction($p, $m);

$this->rentalActions[] = $rentalAction;

switch(DEBUG_MODE) {

case 'echo':

print $m->getName() . ' si vypůjčil publikaci: '

. $p->getCategory() . "";

break;

case 'log':

error_log($m->getName() . ' si vypůjčil publikaci: '

. $p->getCategory() . "",

3, './library.log');


Část I Úvod do návrhu softwaru

34

break;

}

return $rentalAction;

}

// ... ostatní metody třídy

} Pomocí konstanty DEBUG_MODE můžete přepínat mezi jednoduchými hlášeními vypisovanými na obrazovku a zapisovanými do protokolovacího souboru funkcí error_log(). K tomu je nutné přidat do skriptu následující řádek, umožňující centrální řízení způsobu ladění:

define('DEBUG_MODE', 'log'); Co však na prvý pohled vypadá jako komfortní řešení, je v konečném důsledku jen velká slabina aplikace. Na každém místě, kde chcete vložit ladicí kód,musíte vložit devět řádků kódu. Tím bude zdrojový kód vaší aplikace o něco delší, a aplikace se tak stane pomalejší a obtížně udržovatelná. Na tomto místěpřichází na řadu základní pravidlo znovupoužitelnosti kódu.

Znovupoužitelnost kódu

Určitě vás napadlo, že byste se měli vyhýbat duplicitnímu kódu, který častovzniká při postupu ve stylu „Copy & Paste“. Při každé změně tohoto kódu (například

při změně názvu souboru nebo při přidání třetího ladicího režimu) je nutnéprovést změnu na mnoha místech kódu.

Zabránit tomu můžete tím, že duplicitní kód přesunete do samostatné metody,

kterou na potřebných místech jen zavoláte. Nová metoda třídy Library bude

vypadat následovně:

protected function debug($message) {

switch(DEBUG_MODE) {

case 'echo':

print $message . "";

break;

case 'log':

error_log($message . "", 3, './library.log');

break;

}

}


Kapitola 1 Základní pravidla při návrhu softwaru

35

Nové metodě debug() je nutné předat řetězec se zprávou, která se má nějakzpracovat. Tato metoda na základě konstanty DEBUG_MODE rozhodne, zda se zadaná

informace vypíše na obrazovku nebo se zapíše do protokolovacího souboru.

Následně je zapotřebí upravit i metody, které mají novou metodu



       
Knihkupectví Knihy.ABZ.cz - online prodej | ABZ Knihy, a.s.
ABZ knihy, a.s.
 
 
 

Knihy.ABZ.cz - knihkupectví online -  © 2004-2018 - ABZ ABZ knihy, a.s. TOPlist