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

je prázdný
a
b

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

Návrhové vzory v PHP
-12%
sleva

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)
Titul doručujeme za 4 pracovní dny
Vaše cena s DPH:  499 Kč 439
+
-
rozbalKdy zboží dostanu
14,6
bo za nákup
rozbalVýhodné poštovné: 39Kč
rozbalOsobní odběr zdarma

hodnoceni - 75.3%hodnoceni - 75.3%hodnoceni - 75.3%hodnoceni - 75.3%hodnoceni - 75.3% 87%   celkové hodnocení
3 hodnocení + 0 recenzí

Specifikace
Nakladatelství: » Computer press
Médium / forma: Tištěná kniha
Rok vydání: 2012-02-15
Počet stran: 320
Rozměr: 167 x 225 mm
Úprava: 320 stran : ilustrace
Vydání: 1. vyd.
Spolupracovali: překlad Lukáš Krejčí
Vazba: brožovaná lepená
Téma: návrhové vzory
ISBN: 9788025133385
EAN: 9788025133385
Ukázka: » zobrazit ukázku
Popis / resumé

Kniha určená vývojářům, kteří mají zkušenosti s programováním v jazyce PHP. Na praktických příkladech seznamuje s různými návrhovými vzory pro vývoj aplikací v PHP.

Popis nakladatele

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ů. ([23 vzorových postupů pro rychlejší vývoj])

Předmětná hesla
Kniha je zařazena v kategoriích
Marian Böhmer - další tituly autora:
Recenze a komentáře k titulu
Zatím žádné recenze.


Ukázka / obsah
Přepis ukázky

49

KAPITOLA 2

Návrhový vzor

Singleton

Jazyk PHP 5 vám pomocí klíčových slov public, protected a private umožňuje

kontrolovat, kdo získá přístup k určitým atributům a metodám třídy. Dále vám

jazyk PHP 5 umožňuje omezit to, co může být při odvozování tříd přepsané,

a dokonce i to, co přepsané být musí. Jedno vám však jazyk PHP neumožňuje:

nedokážete totiž omezit počet instancí dané třídy. A právě k tomuto účeluslouží návrhový vzor Singleton.

Návrhový vzor Singleton je jeden z nejjednodušších návrhových vzorůa zároveň i jeden z nejpoužívanějších. Možná jste jej už použili, aniž byste věděli, že

se jedná o návrhový vzor.

Problém

Ve vzorovém příkladu z předchozí kapitoly jste vyčlenili kód pro ladění aplikací

ze třídy Library a zapouzdřili jej do nové třídy. Tím jste umožnili tomuto kódu

spolupracovat i s ostatními třídami. Při vytváření instance třídy Libraryjednoduše předáte implementaci rozhraní Debugger konstruktoru:

$debugger = new DebuggerEcho();

$library = new Library($debugger);


Část II Tvořivé vzory

50

Chcete-li odladit i třídy Book a Member, může příslušný kód vypadat následovně:

$debuggerBook = new DebuggerEcho();

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

$debuggerMember = new DebuggerEcho();

$member = new Member($debuggerMember, 1, 'Marian Böhmer'); Tímto způsobem jste vytvořili tři instance stejné třídy a tím spotřebovali skoro třikrát tolik paměti. Knihovna však obsahuje určitě více než jednu publikaci a má registrovaných více než jednoho člena. Spotřeba paměti tedy bude sezvyšujícím se počtem publikací a členů knihovny neustále narůstat. Když se ale na objekt Debugger podíváte blíže, hned vás napadne, že není potřebné pro každou publikaci a  každého člena používat samostatný objekt typu Debugger; tento objekt se nakonec používá jen na vypsání předaných hlášení a neví nico objektu, který jej používá. Ideální by bylo, kdybyste mohli pro každou publikaci a každého členaknihovny používat stejný objekt typu Debugger – tím byste ušetřili množství paměti a vyhnuli se zbytečnému vytváření dalších objektů. S růstem knihovny budou vytvářené objekty typu Debugger na stále nových místech, a nikdy tak nebudete mít jistotu, který z nich byl vytvořený jak první. V takovém případě potřebujete k objektu typu Debugger centrální přístupový bod.

Účel návrhového vzoru

Tohoto centrálního přístupového bodu docílíte pomocí návrhového vzoruSingleton.

Návrhový vzor Singleton zajistí, že z  určité třídy může existovat nejvíce jedna

instance, a poskytne k ní globální přístupový bod.

Pro aplikování tohoto vzoru na výše popsaný problém je nutné vykonatnásledující kroky:

1. Poskytnout centrální bod pro přístup k instanci třídy Debugger.

2. Tento centrální přístupový bod musí vždy nabízet přístup ke  stejnému

objektu nezávisle na počtu volaní.

3. Zabránit možnosti vytvoření další instance třídy.


Kapitola 2 Návrhový vzor Singleton

51

Implementace

Vytvoříte-li v kódu objekt typu Debugger na místě, kde jej chcete použít, nemáte

žádnou možnost zji stit, zda už daný objekt existuje. Pro vytvoření instanceobjektu na centrálním místě přesuňte tento kód do nové metody. Protože k vytvoření

objektu nejsou nutné žádné další informace, použijte k tomu statickou metodu,

tj. metodu třídy, kterou lze zavolat bez nutnosti vytvoření instance této třídy:

namespace czk1886debuggers;

class DebuggerEcho implements Debugger {

public static function getInstance() {

$debugger = new self();

return $debugger;

}

public function debug($message) {

print $message . "";

}

} Ve statické metodě getInstance() vytvoříte novou instanci třídy DebuggerEcho, kterou následně vrátíte. Místo vytvoření objektu typu Debugger pomocíoperátoru new můžete nyní k tomuto účelu použít novou metodu:

use czk1886debuggersDebuggerEcho;

$debugger1 = DebuggerEcho::getInstance();

$debugger1->debug('Lorem ipsum dolor sit amet.');

$debugger2 = DebuggerEcho::getInstance();

$debugger2->debug('Proin fringilla bibendum sagittis.');

if ($debugger1 === $debugger2) {

print '$debugger1 === $debugger2';

} else {

print '$debugger1 !== $debugger2';

} V tomto příkladu objekt nevytváříme přímo v místě, kde jej potřebujeme, nicméně počet vytvořených objektů se nezměnil, protože při každém volání metodygetInstance() se vytvoří nový objekt typu Debugger. To potvrzuje i výpis z příkladu:


Část II Tvořivé vzory

52

Lorem ipsum dolor sit amet.

Proin fringilla bibendum sagittis.

$debugger1 !== $debugger2 Z toho vyplývá, že metoda getInstance() by měla obsahovat více logiky a při každém volaní provést následující kroky:

1. Při volání ověřit, zda už existuje instance třídy.

2. Pokud ne, vytvořit instanci třídy pomocí operátoru new a uložit ji.

3. Vrátit uloženou instanci. Aby bylo možné použít stejný objekt vícekrát, musí být uložený v rámcimetody getInstance(). Vzhledem k tomu, že tato metoda je definovaná jakostatická, musí být atribut, který bude uchovávat instanci dané třídy, také definovaný jako statický:

namespace czk1886debuggers;

class DebuggerEcho implements Debugger {

private static $instance = null;

public static function getInstance() {

if (null == self::$instance) {

self::$instance = new self();

}

return self::$instance;

}

public function debug($message) {

print $message . "";

}

} Třídu DebuggerEcho jste v  tomto kroku doplnili o  statický atribut $instance. Metoda getInstance() při jejím volání ověří, zda $instance již obsahujeinstanci třídy. Pokud ne, vytvoří se nová instance, která se přiřadí do atributu a kterou následně metoda vrátí. Při opětovném provedení testovacího skriptu již docílíme požadovaného efektu:

Lorem ipsum dolor sit amet.

Proin fringilla bibendum sagittis.

$debugger1 === $debugger2


Kapitola 2 Návrhový vzor Singleton

53

V této chvíli je úplně jedno, jak často se bude metoda getInstance() volat,aplikace bude používat vždy stejný objekt, čímž se ušetří systémové prostředky.

Skryté problémy

Návrhový vzor Singleton s sebou nese i pár skrytých problémů. Co se stane, pokud

vaši týmoví kolegové nebudou vědět, že pro získání objektu typu Debugger mají

použít metodu getInstance()? Vytvoří jej klasickým způsobem:

use czk1886debuggersDebuggerEcho;

// váš objekt debugger1

$debugger1 = DebuggerEcho::getInstance();

$debugger1->debug('Lorem ipsum dolor sit amet.');

// objekt debugger2 vašeho kolegy

$debugger2 = new DebuggerEcho();

$debugger2->debug('Proin fringilla bibendum sagittis.');

if ($debugger1 === $debugger2) {

print '$debugger1 === $debugger2';

} else {

print '$debugger1 !== $debugger2';

} Vytvořené objekty znovu nejsou stejné a znovu dochází k plýtvání pamětí.Musíte tedy svým týmovým kolegům zakázat možnost vytvářet instancesamostatně a tím je donutit používat metodu getInstance(). Řešení tohoto problému je velmi jednoduché. Použití konstruktoru mimo třídu zakážete tak, že jejdeklarujete jako protected:

namespace czk1886debuggers;

class DebuggerEcho implements Debugger {

// ... statický atribut a metoda getInstance()

protected function __construct() {}

public function debug($message) {

print $message . "";

}

}


Část II Tvořivé vzory

54

Pokud se v  této chvíli pokusí některý z  vašich kolegů vytvořit novou instanci

objektu typu Debugger, zareaguje na to interpret jazyka PHP následující chybou:

Fatal error: Call to protected czk1886debuggersDebuggerEcho::

__construct() from invalid context in test.php on line 10 Váš kolega bude muset místo toho použít k získání objektu metodu getInstance(). Vynalézaví kolegové, kteří přesto budou chtít vytvořit novou instanci objektu, by mohli přijít na myšlenku klonovat objekt, který získají pomocí metody getInstance():

use czk1886debuggersDebuggerEcho;

$debugger1 = DebuggerEcho::getInstance();

$debugger1->debug('Lorem ipsum dolor sit amet.');

$debugger2 = clone $debugger1;

$debugger2->debug('Proin fringilla bibendum sagittis.');

if ($debugger1 === $debugger2) {

print '$debugger1 === $debugger2';

} else {

print '$debugger1 !== $debugger2';

} Po provedení tohoto testovacího skriptu se znovu ukáže, že se používají dvě instance třídy. I  když vám nikdo takovéto kolegy nepřeje, nemůžete si být se současným řešením problému nikdy jistí, že skutečně existuje jen jednainstance třídy. Z toho vyplývá, že jste požadavek číslo tři zatím nesplnili na 100 %. Naštěstí vám jazyk PHP také umožňuje změnit chování třídy při klonování, k čemuž stačí implementovat metodu s názvem __clone(). Klonování objektu zakážete tím, že zakážete volání metody __clone() mimo danou třídu:

namespace czk1886debuggers;

class DebuggerEcho implements Debugger {

// ... statický atribut a metoda getInstance()

protected function __construct() {}

private function __clone() {}


Kapitola 2 Návrhový vzor Singleton

55

public function debug($message) {

print $message . "";

}

} Při opakovaném pokusu klonovat objekt typu Debugger obdrží váš kolegachybové hlášení, které mu oznamuje, že klonování objektu je zakázané:

Fatal error: Call to private czk1886debuggersDebuggerEcho::

__clone() from context '' in test.php on line 10 Tím jste zabezpečili, že vždy může existovat maximálně jeden objekt třídyDebuggerEcho, a implementovali jste tudíž svého prvého jedináčka.

POZNÁMKA

Možná se divíte, proč byl konstruktor deklarovaný jako protected a metoda __

clone() jako private. Důvodem jsou možnosti, které poskytuje dědění. Vpřípadě konstruktoru chcete umožnit třídám, které jsou potomky třídy DebuggerEcho,

aby jej mohly přepsat. Takto deklarovaný konstruktor není sice možné použít mimo

třídu, avšak je možné jej použít na jeho obvyklé úlohy.

V případě metody __clone() toto není nutné a má být jen zamezení její používání.

Definice

Návrhový vzor Singleton zajistí, že z  určité třídy může existovat nejvíce jedna

instance, a poskytne k ní globální přístupový bod.

Pro implementaci tohoto návrhového vzoru jsou vždy nutné následující čtyři

kroky:

1. Definovat statický atribut, který obsahuje instanci objektu třídy.

2. Implementovat statickou metodu, která vrací objekt z bodu 1 a v případě,

že neexistuje, jej vytvoří.

3. Zabránit vytvoření nové instance pomocí operátoru new tak, že budekonstruktor deklarovaný jako protected.

4. Zajistit, aby objekt třídy nemohl být klonovaný, k čemuž stačí metodu __

clone() deklarovat jako private.

Na obrázku 2.1 je zobrazený diagram jazyka UML pro obecný návrhový vzor

Singleton a na obrázku 2.2 je jeho konkrétní implementace.

POZNÁMKA

Možná se divíte, proč byl konstruktor deklarovaný jako protected a metoda __

clone() jako private. Důvodem jsou možnosti, které poskytuje dědění. Vpřípadě konstruktoru chcete umožnit třídám, které jsou potomky třídy DebuggerEcho,

aby jej mohly přepsat. Takto deklarovaný konstruktor není sice možné použít mimo

třídu, avšak je možné jej použít na jeho obvyklé úlohy.

V případě metody __clone() toto není nutné a má být jen zamezení její používání.


Část II Tvořivé vzory

56

Obrázek 2.1: UML diagram návrhového vzoru Singleton

Obrázek 2.2: UML diagram konkrétní implementace

Shrnutí

Použití návrhového vzoru Singleton má pro vaši aplikaci následující dopady:

 Můžete přesně kontrolovat způsob, jakým se přistupuje ke tříděimplemen

tující tento návrhový vzor.

 Z dané třídy existuje vždy maximálně jedna instance. Druhou instanci třídy

při použití tohoto návrhového vzoru není možné vytvořit. Existují však

různé modifikace tohoto návrhového vzoru, u nichž je povolena i více než

jedna instance.

 Návrhový vzor Singleton vám umožňuje zredukovat počet globálníchpro

měnných nebo je ze zdrojového kódu úplně odstranit. Místo ukládáníglo

bálních instancí tříd v globálním oboru názvů můžete přistupovat k jejich

instancím přes statické metody, čímž udržujete globální obor názvů volný.

Návrhový vzor Singleton je jeden z  nejjednodušších návrhových vzorů, což

může být i důvodem, proč je využívaný i v situacích, kdy to není nutné. Před

jeho nasazením byste se proto měli zamyslet, zda skutečně povolíte jen jednu

instanci třídy, nebo zda je užitečné současné využití více instancía ve skuteč

nosti potřebujete jen centrální přístupový bod k objektu. V posledním případě

byste k tomu mohli využít i návrhový vzor Registry (Registr).

-instance : Singleton

-attribute1

-attribute2

#Singleton()

+getInstance() : Singleton

+method1()

+method2()

Singleton

-instance : DebuggerEcho

#DebuggerEcho()

+getInstance() : DebuggerEcho

-__clone()

DebuggerEcho


Kapitola 2 Návrhový vzor Singleton

57

Další využití

Kromě objektu typu Debugger existují i další možnosti, kde lze využít návrhový

vzor Singleton. Často se například využívá při poskytování centrálníhopřístuového bodu ke konfiguraci aplikace. Při existenci jen jednoho objektu, který

se stará o ukládání konfigurace, získáte hned dvě výhody:

 Pokud se změní nějaká konfigurační hodnota komponenty, platí tato změna

okamžitě pro všechny komponenty.

 Konfigurační soubory stačí načíst jen jednou, což se kladně projeví naspotřebě dostupných zdrojů.

Stejně často se návrhový vzor Singleton používá, pokud aplikace přistupuje

k externím zdrojům, jako jsou například databáze. Použitím jednohocentrálního objektu, který se stará o přístup k databázi, stačí otevřít jen jedno připojení,

které si pak jednotlivé komponenty sdílejí.

Variace návrhového vzoru Singleton

Možná jste si říkali, jak se dá použít návrhový Singleton pro objekty, které mají

být z vnějšku parametrizované. Chcete-li například znovu změnit způsobladění aplikace na protokolování do souboru, avšak nezapisovat všechna hlášení do

jednoho souboru, lze použít pro různé komponenty různé soubory.

Objekt typu Debugger pro protokolování do souboru by mohl vypadat následovně:

namespace czk1886debuggers;

class DebuggerLog implements Debugger {

protected $logfile = null;

public function __construct($logfile) {

$this->logfile = $logfile;

}

public function debug($message) {

error_log($message . "", 3, $this->logfile);

}

}


Část II Tvořivé vzory

58

Při vytváření instance třídy DebuggerLog se konstruktoru předá název souboru,

do něhož se mají předaná hlášení zapisovat. Díky tomu lze zapisovat hlášení do

různých souborů.

use czk1886debuggersDebuggerLog;

$debugger1 = new DebuggerLog('./debugger1.log');

$debugger1->debug('Lorem ipsum dolor sit amet.');

$debugger2 = new DebuggerLog('./debugger2.log');

$debugger2->debug('Proin fringilla bibendum sagittis.'); Jenže v tomto případě již nemůžete využít vzor Singleton, protože chcete povolit více než jednu instanci. To ale chcete umožnit jen v případě, kdy různéinstance zapisují do různých souborů. V případě zápisu do stejného protokolovacího souboru by se měla použít stejná instance. Jednoduchou změnou implementace návrhového vzoru Singleton je i toto možné. Místo jedné globální instancemusíte do statického atributu uložit instanci třídy podle použitého souboru. Tento atribut tedy vyměníte za pole:

namespace czk1886debuggers;

class DebuggerLog implements Debugger {

protected $logfile = null;

private static $instances = array();

public static function getInstance($logfile) {

if (!isset(self::$instances[$logfile])) {

self::$instances[$logfile] = new self($logfile);

}

return self::$instances[$logfile];

}

protected function __construct($logfile) {

$this->logfile = $logfile;

}

private function __clone() {}

public function debug($message) {

error_log($message . "", 3, $this->logfile);

}

}


Kapitola 2 Návrhový vzor Singleton

59

Nyní už stačí jen předat název protokolovacího souboru metodě getInstance().

Následující příklad vytvoří dvě instance třídy DebuggerLog, přestože se metoda

getInstance() bude volat třikrát:

use czk1886debuggersDebuggerLog;

$debugger1 = DebuggerLog::getInstance('./debugger1.log');

$debugger1->debug('Lorem ipsum dolor sit amet.');

$debugger2 = DebuggerLog::getInstance('./debugger2.log');

$debugger2->debug('Proin fringilla bibendum sagittis.');

$debugger3 = DebuggerLog::getInstance('./debugger1.log');

$debugger3->debug('Mauris vitae augue dolor.'); První a poslední volání vrátily stejný objekt, o čemž se můžete přesvědčit i na obrázku 2.3. Obrázek 2.3: Pole instancí upravené implementace návrhového vzoru Singleton Sice jste zde neimplementovali vzor Singleton v klasické podobě, nicméně s touto variací se budete v praxi střetávat velmi často.




       
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