Design patterns
1Un punct de reper pentru a descoperi un programator bun, indiferent de limbajul de programare pe care il utilizeaza, este abilitatea acestuia de a aplica tehnici cunoscute de design al aplicatiei. Design patterns(sau proiectarea modelelor) sunt un un set de solutii ce pot fi aplicate la diverse probleme ce se intalnesc frecvent in cadrul programarii orientate pe obiect.
In teorie, aceste modele nu au legatura cu codul scris de un programator. Sunt niste solutii de eficientizare a problemelor des intalnite, niste indicatii pe care programatorul trebuie sa le transpuna in limbajul de programare pe care il foloseste. Ne vom referi in continuare la aceste modele legat de limbajul PHP, modele care desi pot fi implementate folosind si programarea procedurala, ele sunt evidentiate mai bine cu ajutorul programarii orientate pe obiect.
Singleton
Modelul Singleton este probabil cel mai simplu model. El este facut pentru a permite accesul la o singura resursa care nu va fi niciodata duplicata, dar care trebuie facuta disponibila in orice moment al executiei aplicatiei. Implementarea unui Singleton trebuie sa satisfaca cele doua conditii de acces global si instantiere singulara a resursei respective. Are nevoie de un mecanism de acces la class Singleton fara a instantia un obiect si un mecanism de a pastra informatia asupra resursei ce urmeaza a fi folosita. Astfel acest model poate fi cel mai usor implementat prin crearea unei clase ce va contine o metoda care va crea o noua instanta a clasei, daca aceasta nu exista deja, iar daca exista o va returna pe aceasta. Pentru a fi siguri ca acea clasa nu va fi instantiata in alt fel, constructorul este declarat protejat. Exemplul cel mai simplu este acela in care se pune problema existentei unei singure conexiuni la baza de date:
class database { private static $_singleton; private $_connection; protected function __construct() { $this->_connection = mysql_connect(SERVER, USER, PASSWORD); } public static function getInstance() { if (is_null(self::$_singleton)) { self::$_singleton = new database(); } return self::$_singleton; } } $cnx = database::getInstance();
Asadar constructorul a fost declarat protejat pentru a controla accesul la el si de a da posibilitatea apelarii lui doar din interiorul clasei. Acest lucru este facut cu ajutorul metodei statice getInstance, care verifica la fiecare apel al ei daca exista definit membrul static $_singleton, caz in care il va returna, sau va incerca sa creeze unul nou. Odata creat, metoda getInstance() nu va mai incerca sa creeze unul nou ci-l va retuna pe cel creat tot timpul.
Factory
Modelul Factory se foloseste in scenariile in care exista o clasa generica (fabrica) care are posibilitatea de a crea o instanta a una sau mai multe clase specializate in rezolvarea unei aceleasi probleme dar in diferite moduri. Un astfel de exemplu il reprezinta stocarea datelor de configurare intr-o aplicatie. Datele de configurare, precum credentialele pentru conectarea la baza de date, sau caile de acces la diverse directoare, pot fi stocate in mai multe feluri: in fisiere XML, in fisiere INI sau chiar in baza de date. Astfel putem crea un mecanism care sa returneze un obiect ce va sti sa lucreze cu un anume mod de stocare a acestor date de configurare.
class configuration { const STORE_IN_INI = 1; const STORE_IN_DB = 2; const STORE_IN_XML = 3; public static function factory($type = self::STORE_IN_INI) { switch ($type) { case self::STORE_IN_INI: return new configuration_ini(); case self::STORE_IN_DB: return new configuration_db(); case self::STORE_IN_XML: return new configuration_xml(); default: throw new Exception('Tip de stocare necunoscut'); } } }
Este evident faptul ca toate cele 3 clase specializate de tratare a fisierelor de configurare (ini, xml, db) trebuiesc definite si implementate, un avantaj fiind definirea lor conform unei clase abstracte. Apelarea “fabricii†se face dupa cum urmeaza:
$storage = configuration::factory(configuration::STORE_IN_XML);
Registry
Modelul Registry este un model Singleton mai evoluat, in sensul ca permite stocarea mai multor resurse, ca intr-un registru. Un exemplu ar fi acela in care, desi avem conexiunea stabilita catre baza de date printr-un Singleton, si prin aceasta conexiune se fac toate interogarile, exista posibilitatea ca din aplicatie sa fie nevoie de conexiunea in paralel catre o alta baza de date pentru a efectua si acolo diverse operatiuni. Cu un simplu Singleton nu s-ar fi putut realiza asa ceva insa cu un Registry acest lucru este posibil. Un astfel de Registry va trebui sa implementeze metode de adaugare, verificare a existentei si de returnare a informatiilor cerute.
class registry { private static $_register; public static function add(&$element, $name) { $name = strtolower($name); self::$_register[$name] = $element; } public static function exists($name) { $name = strtolower($name); if (array_key_exists($name, self::$_register)) { return true; } return false; } public static function &get($name) { $name = strtolower($name); if (self::exists($name)) { return self::$_register[$name]; } else { throw new Exception('Elementeul cerut nu exista in registru.'); } } }
O folosirea a cestul model este urmatorul cu precizarea ca in acest exemplu clasa database nu este un Singleton:
$db = new database(); registry::add($db, 'dbCnx'); /* verificarea conexiunii */ if (registry::exists('dbCnx')) { $db = registry::get('dbCnx'); }
Model-View-Controller
Spre deosebire de celelate modele discutate anterior, Model-View-Controller(denumit si MVC) este un model destul de complex. Scopul lui este de a oferi o metoda de separare dintre logica aplicatiei (model), modului de afisare (view) si structura decizionala (controller), aplicatiile MVC fiind astfel usor de modificat atunci cand se doreste modificarea doar a modului de afisare sau a modului in care este tratata o cerere.
Logica unei astfel de aplicatii este urmatoare: o cerere este facuta catre aplicatie si este apelat controller-ul care va decide cum va trata cererea. Controller-ul va chema o clasa din Model, care efectiv va efectua interogari catre baza de date, prelucrarile necesare ale datelor sau orice alte operatiuni necesare. Rezultatul, de regula un set de date, va fi intors catre Controller care va transmite aceste date partii vizuale a aplicatiei(View) unde deja exista o structura de afisare a datelor ce tocmai au fost primite. Avantajul enorm al acestui model este separarea clara intre cele 3 compomente si usurinta cu care se pot extinde aplicatiile dezvoltate pe acest model.
Autor: George Enciu
[…] Evident, solutia sta in mainile noastre. Trebuie sa gandim o modalitate de lucru ce se potriveste perfect pentru orice tip de proiect, spunem noi, trebuie sa stabilim arhitectura ce o au in comun toate proiectele. Practic, un punct de reper pentru a descoperi un programator bun, indiferent de limbajele in care lucreaza, este abilitatea acestuia de a aplica tehnici cunoscute in industrie pentru a arhitecturiza proiectele intr-un mod eficient. Design Patterns (sau proiectarea modulelor) sunt un set de solutii ce pot fi aplicate la diverse probleme ce se intalnesc frecvent in cadrul programarii orientate pe obiecte (POO). Cateva din cele mai populare design patternuri folosite la scara larga sunt Singleton, Factory, Registry si MVC. Acestea sunt prezentate foarte frumos in articolul Design Patterns de pe Tutorial Web sau pe WorldIT. […]