Prototype
Proprietati
Tip: Creational, Obiect
Nivel: O singura clasa
Scop
Face mai usoara crearea dinamica a obiectelor prin definirea de clase ale caror obiecte pot crea duplicate ale lor.
Introducere
Īn PIM se doreste ca o adresa sa se poata copia, pentru ca utilizatorul sa nu fie nevoit sa introduca toata informatia necesara crearii unui nou contact. O posibila modalitate de rezolvare implica urmatorii pasi:
Se creeaza un nou obiect Address
Se copiaza īn cāmpurile sale valorile cāmpurilor unui obiect Address existent.
Solutia de mai sus, chiar daca rezolva problema, violeaza unul dintre principiile OO, principiul īncapsularii. Apelurile de metode care copiaza informatia din obiectul Address existent trebuie puse īn afara clasei Address. Aceasta īnseamna ca va fi din ce īn ce mai greu sa se gestioneze codul clasei Address, deoarece el va fi īmprastiat peste tot īn proiect. De asemenea, va fi dificila reutilizarea clasei Address īn proiecte noi, din acelasi motiv.
Codul de copiere apartine clasei Address, asa ca ideea este sa definim o metoda "copy" īn aceasta clasa. Metoda va produce un duplicat al obiectului Address cu aceleasi valori ale cāmpurilor ca si obiectul originar - prototipul.
Apelul metodei pe un obiect Address existent rezolva problema īntr-o maniera mult mai usor de īntretinut, mult mai apropiata de spiritul si practica OO.
Aplicabilitate
sablonul Prototype se foloseste cānd se doreste crearea unui obiect care este copie a unuia existent.
Descriere
sablonul Prototype este bine numit; la fel ca si īn cazul altor prototipuri, el are ca argument un obiect care este folosit ca baza pentru a crea o noua instanta cu aceeasi stare. Furnizarea unui comportament "creeaza pe baza unei stari existente" permite programelor sa efectueze operatii precum copiere la cererea utilizatorului si sa initializeze obiectele cu o stare care a fost stabilita prin folosirea sistemului. Aceasta este adesea preferabila initializarii obiectului cu o multime de valori generice.
Exemple clasice ale acestui sablon exista īn editoarele text si grafice, unde operatiile copy-paste pot īmbunatati dramatic productivitatea utilizatorului. Unele aplicatii de gestiune folosesc aceasta abordare, producānd un model initial dintr-un obiect specific aplicatiei existent. Ulterior, copia se modifica pentru a fi adusa la starea dorita.
Implementare
Diagrama de clase a sablonului Prototype este ilustrata īn Figura 1.4
Figura 1.4. Diagrama de clase a sablonului Prototype
Pentru a implementa sablonul Prototype, avem nevoie de urmatoarele:
Prototype - Furnizeaza o metoda copy. Aceasta metoda returneaza o instanta a aceleiasi clase si cu aceeasi stare ca si instanta Prototype initiala. Noua instanta poate fi o copie de adāncime sau de suprafata a originalului (vezi sectiunea Avantaje si dezavantaje
Avantaje si dezavantaje
sablonul
Prototype este util deoarece el permite sistemelor sa faca copii ale
obiectelor folosibile, cu variabilele de stare setate la o valoare (ipotetic)
semnificativa, īn loc sa creeze obiecte cu o stare de baza
definita īn constructor. Un exemplu de folosire a acestui sablon este
ilustrat īn Figura 1.5
Figura 1.5. Exemplul de folosire a sablonului Prototype
Un element cheie al acestui sablon este modalitatea īn care se face copierea: īn adāncime sau la suprafata. Copierea la suprafata duplica numai elementele de pe primul nivel al clasei; copierea este mai rapida, īnsa nu este adecvata tuturor posibilelor utilizari ale copiei. Deoarece referintele se copiaza din original īn copie, ale vor referi acelasi obiect (cāmpurile referinta cu acelasi nume din original si din copie). Īn acest fel, obiectele de nivel mai jos sunt partajate īntre diversele copii ale obiectului de nivel mai īnalt; modificarea unuia dintre obiectele de nivel jos va afecta toate copiile.
Operatia de copiere īn adāncime nu duplica doar atributele de pe primul nivel, ci si obiectele de pe nivelele inferioare. Ea dureaza mai mult decāt copierea de suprafata, si poate fi foarte costisitoare pentru obiectele cu structura foarte complexa. Avantajul este ca modificarile īntr-o copie sunt izolate: ele nu afecteaza obiectele similare din celelalte copii.
Prin natura sa, metoda clone din clasa Object sprijina o singura forma de copiere. Pentru cazurile unde trebuie folosite metode multiple de initializare post-creare.
Variatiuni la acest sablon
Variatiunile la acest sablon includ constructorul de copiere si metoda clone
Constructorul de copiere - este o varianta a prototipului. El are ca parametru un argument din aceeasi clasa si īntoarce o noua copie cu aceeasi stare ca si argumentul.
Exemplul1 Copy constructor
public class Prototype
// restul codului
Un exemplu este clasa String, unde se poate crea o noua instanta a clasei String prin apelul: new String("text");
Avantajul acestei variante este claritatea: intentia de a crea o noua instanta este foarte clara, īnsa se poate efectua o singura modalitate de copiere (la suprafata sau īn adāncime). Este posibila proiectarea unui constructor care sa faca ambele modalitati de copiere, caz īn care el va avea doua argumente: obiectul supus copierii si un al doilea argument care specifica modalitatea de copiere.
Un dezavantaj al acestei variante este acela ca īn codul sau constructorul de copiere trebuie sa testeze argumentul referinta pentru a vedea daca reprezinta un obiect valid. Īn implementarea normala a sablonului Prototype, metoda este sigura ca este apelata pe un obiect valid.
Metoda clone - Limbajul de programare Java defineste o metoda clone īn clasa java.lang.Object-superclasa tuturor claselor Java. Pentru a folosi metoda pe o anumita instanta, clasa respectivei instante trebuie sa implementeze interfata java.lang.Clonable care indica faptul ca o instanta a clasei se poate copia. Deoarece metoda clone este declarata protected in clasa Object, ea trebuie suprascrisa pentru a o face publica.
Conform celor spuse de Bloch, "clone() trebuie folosita judicios" [Bloch01] Dupa cum s-a precizat, o clasa trebuie sa implementeze interfata Clonable, īnsa aceasta interfata nu ne da garantia ca obiectul se poate clona. Interfata Clonable nu defineste metoda clone, prin urmare este posibil ca metoda clone sa nu fie disponibila cānd nu este suprascrisa. Un alt dezavantaj al metodei clone este acela ca trebuie sa returneze un obiect de tipul Object, necesitānd conversia la tipul clasei cerute, īnainte de utilizarea sa.
sabloane īnrudite
Abstract Factory - sabloanele Abstract Factory pot folosi sablonul Prototype pentru a crea obiecte noi bazate pe folosirea curenta a sablonului Factory.
Factory Method - sabloanele metoda Factory pot folosi un sablon Prototype care sa aiba menirea unui schelet de creare de noi obiecte.
Example
Clasa Address din acest exemplu foloseste sablonul Prototype pentru a crea o adresa pe baza uneia existente. Functionalitatea esentiala a sablonului este definita īn interfata Copyable
Exemplul 2 Copyable.java
1. public interface Copyable
Interfata Copyable defineste o metoda copy si garanteaza ca orice clasa ce implementeaza interfata va defini o operatie copy. Acest exemplu produce o copie de suprafata - se copiaza referintele la obiecte din adresa originala īn duplicat.
Codul sursa demonstreaza de asemenea o caracteristica importanta a operatiei copy: nu este necesar sa se copieze toate cāmpurile. Īn exemplu, tipul adresei nu este copiat īn noul obiect. Utilizatorul va specifica manual noul tip de adresa folosind interfata cu utilizatorul a PIM.
Exemplul 3 Address.java
1. public class Address implements Copyable
public Address(String initStreet, String initCity,
String initState, String initZip)
public Address(String initType)
public Address()
public String getType()
public String getStreet()
public String getCity()
public String getState()
public String getZipCode()
public void setType(String newType)
public void setStreet(String newStreet)
public void setCity(String newCity)
public void setState(String newState)
public void setZipCode(String newZip)
public Object copy()
public String toString()
|