This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revision Both sides next revision | ||
laboratoare:static-final [2019/10/19 21:08] Adriana Draghici |
laboratoare:static-final [2019/10/20 14:57] Radu Matei [Cuvântul-cheie "final". Obiecte immutable] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | = Static și final = | + | = Static și final; Singleton Design Pattern = |
== Obiective == | == Obiective == | ||
Line 79: | Line 79: | ||
} | } | ||
</code> | </code> | ||
- | In acest caz, numarul de obiecte create in memorie este unul foarte mare. Dintre acestea doar cel rezultat la final este util. Pentru a preveni alocarea nejustificata a obiectelor de tip String care reprezinta pasi intermediari in obtinerea sirului dorit putem alege sa folosim clasa StringBuilder creata special pentru a efectua operatii pe siruri de caractere. | + | În acest caz, numărul de obiecte create în memorie este unul foarte mare. Dintre acestea doar cel rezultat la final este util. Pentru a preveni alocarea nejustificată a obiectelor de tip Strîng care reprezintă pași intermediari în obținerea șirului dorit putem alege să folosim clasa StringBuilder creată special pentru a efectua operații pe șiruri de caractere. |
<code java5> | <code java5> | ||
public static String concatenareCuClasaStringBuilder(){ | public static String concatenareCuClasaStringBuilder(){ | ||
Line 90: | Line 90: | ||
</code> | </code> | ||
- | Cuvantul cheie final poate fi folosit si in alt context decat cel prezentat anterior. De exemplu, aplicat unei clase impiedica o eventuala derivare a acestei clase prin mostenire. | + | Cuvântul cheie final poate fi folosit și în alt context decât cel prezentat anterior. De exemplu, aplicat unei clase împiedică o eventuală derivare a acestei clase prin moștenire. |
<code java5> | <code java5> | ||
final class ParentClass { | final class ParentClass { | ||
Line 100: | Line 100: | ||
</code> | </code> | ||
- | In mod similar, in cazul in care aplicam cuvantul cheie final unei metode, acest lucru impiedica o eventuala suprascriere a acelei metode | + | În mod similar, în cazul în care aplicăm cuvântul cheie final unei metode, acest lucru împiedică o eventuală suprascriere a acelei metode. |
<code java5> | <code java5> | ||
class ParentClass { | class ParentClass { | ||
Line 244: | Line 244: | ||
* pentru obiecte de tip //Factory//. | * pentru obiecte de tip //Factory//. | ||
- | Exemple din API-ul Java: | + | Exemple din API-ul Java: [[http://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html | java.lang.Runtime]], [[http://docs.oracle.com/javase/8/docs/api/java/awt/Toolkit.html | java.awt.Toolkit]] |
- | * [[http://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html | java.lang.Runtime]] | + | |
- | * [[http://docs.oracle.com/javase/8/docs/api/java/awt/Toolkit.html | java.awt.Toolkit]] | + | |
Din punct de vedere al design-ului și testarii unei aplicații de multe ori se evită folosirea acestui pattern, în test-driven development fiind considerat un **//anti-pattern//**. A avea un obiect Singleton a carei referință o folosim peste tot prin aplicație introduce multe dependențe între clase și îngreunează testarea individuală a acestora. | Din punct de vedere al design-ului și testarii unei aplicații de multe ori se evită folosirea acestui pattern, în test-driven development fiind considerat un **//anti-pattern//**. A avea un obiect Singleton a carei referință o folosim peste tot prin aplicație introduce multe dependențe între clase și îngreunează testarea individuală a acestora. | ||
Line 297: | Line 295: | ||
* o constantă MAGIC_NUMBER având orice valoare doriți | * o constantă MAGIC_NUMBER având orice valoare doriți | ||
* un String constant MAGIC_STRING, lung de minim 20 de caractere, generat random | * un String constant MAGIC_STRING, lung de minim 20 de caractere, generat random | ||
- | * un constructor care primește: un String numit ''firstName'', un String numit ''lastName'' și un int numit ''age'' | + | * un constructor care primește: un String numit ''name'' |
* o metodă ''getPassword()'' care va returna parola | * o metodă ''getPassword()'' care va returna parola | ||
- | * parola se construiește concatenand următoarele șiruri: | + | * parola se construiește concatenand următoarele șiruri: |
- | * șirul format din ultimele ''(age % 3)'' litere din firstName | + | |
* un șir random de lungime MAGIC_NUMBER, generat cu ''RandomStringGenerator'' și cu un alfabet obținut din 10 caractere obținute random din MAGIC_STRING | * un șir random de lungime MAGIC_NUMBER, generat cu ''RandomStringGenerator'' și cu un alfabet obținut din 10 caractere obținute random din MAGIC_STRING | ||
- | * și șirul format prin conversia la String a numărului (age + lungimea lui lastName). | + | * și șirul format prin conversia la String a lungimii lui name + un numar intreg generat random din intervalul [0,100] |
* Pentru subșiruri și alte metode utile consultați documentația clasei [[http://docs.oracle.com/javase/8/docs/api/java/lang/String.html | String]] | * Pentru subșiruri și alte metode utile consultați documentația clasei [[http://docs.oracle.com/javase/8/docs/api/java/lang/String.html | String]] | ||
- | - (**3p**) Modificati implementarea clasei PasswordMaker astfel incat | + | - (**3p**) Modificați implementarea clasei PasswordMaker astfel încât să respecte conceptul de **Singleton pattern** (să permită instanțierea unei singur obiect) |
- | * Sa respecte conceptul de Singleton pattern (sa permita instantierea unei singur obiect) | + | * Pornind de la exemplul de Singleton din textul laboratorului implementați o versiune care urmează principiul de Eager Initialization (singura instanța a clasei este creată la pornirea aplicației, indiferent dacă este necesar sau nu) |
- | * Implementati Singleton pattern folosind conceptul de Eager Initialization (singura instanta a clasei este creata la pornirea aplicatiei, indiferent daca este necesar sau nu) | + | * Implementați o versiune de Singleton în care variabila ''instance'' este inițializata într-un bloc static |
- | * Modificati implementarea anterioara urmand conceptul de Lazy Initialization (singura instanta a clasei este creata doar atunci cand este nevoie de ea) | + | * Adăugați un contor care să numere de câte ori a fost accesată metodă ''getInstance()''. E nevoie ca acest contor să fie static? |
- | - (**4p**) Să se implementeze o clasă ''MyImmutableArray'' care sa contina: | + | * //Tema de gândire:// Ce se va întâmplă dacă folosim conceptul de Singleton pattern într-un program paralelizat, care rulează pe mai multe linii de execuție (thread-uri). Ce probleme ar putea să apară? |
- | * un field de ''ArrayList<Integer> immutableArray;'' neinitializat in prima faza | + | - (**3p**) Să se implementeze o clasă ''MyImmutableArray'' care să conțină: |
- | * un constructor care primeste un ArrayList<Integer> si copiaza toate elementele din acel array in ''immutableArray'' | + | * un field de ''ArrayList<Integer> immutableArray;'' neinitializat în primă faza |
- | * o metoda getArray implementata in asa fel incat field-ul ''immutableArray'' sa ramana immutable | + | * un constructor care primește un ArrayList<Integer> și copiază toate elementele din acel array în ''immutableArray'' |
- | - (**1p**) Testati clasa ''MyImmutableArray'' demonstrand faptul ca instantele acestei clase sunt imutabile | + | * o metodă getArray implementată în așa fel încât field-ul ''immutableArray'' să rămână immutable |
+ | - (**1p**) Testați clasa ''MyImmutableArray'' demonstrând faptul că instanțele acestei clase sunt imutabile | ||