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
![]() |
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()
|