This shows you the differences between two versions of the page.
|
poo:laboratoare:12 [2021/01/11 17:57] carmen.odubasteanu |
poo:laboratoare:12 [2026/01/12 07:49] (current) george.tudor1906 |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ===== Laboratorul 12. ===== | ||
| + | ===== Laboratorul 12 – Genericitate. Design Patterns 2 ===== | ||
| - | ==== Probleme ==== | + | {{:poo:laboratoare:arhiva12_genericitate_dp2.zip|Arhiva laborator}} |
| + | === Problema 1 === | ||
| - | === 1) Singleton === | + | Pornind de la codul de mai jos, asigurați faptul că se va apela codul aferent tipului |
| + | dinamic al parametrului, definind clasele Hero, Warrior, Ninja, Rogue și StormFire, | ||
| + | în mod minimal! | ||
| - | Realizati o aplicatie in care veti construi o clasa **ShopSingleton** folosind design pattern-ul **Singleton**. Clasa va avea urmatorii membrii: | + | <code java> |
| - | * name (String) | + | public class Binding { |
| - | * products (o lista de produse) | + | public static void main(String args[]) { |
| - | In acest caz veti avea o clasa **Product** care descrie un produs, caracterizat prin pret, care va fi float si un nume, care va fi un String. | + | Hero h1 = new Warrior(), h2 = new Ninja(); |
| + | Hero h3 = new Rogue(); | ||
| + | BadLuck bl = new StormFire(); | ||
| + | bl.execute(h1); | ||
| + | bl.execute(h2); | ||
| + | bl.execute(h3); | ||
| + | } | ||
| + | } | ||
| - | In **ShopSingleton** va exista o metoda void numita **//showProducts//**, care va afisa produsele din magazin. | + | abstract class BadLuck { |
| - | Veti avea o clasa Test, in care veti avea implementate urmatoarele metode: | + | abstract void execute(Hero h); |
| - | * addProduct(Product) - veti adauga un produs in magazin, | + | abstract void execute(Warrior w); |
| - | * removeProduct(Product) - eliminarea unui produs din magazin, | + | abstract void execute(Ninja n); |
| - | * getCheapestProduct() - va returna produsul cel mai ieftin din magazin | + | abstract void execute(Rogue r); |
| - | Si un main in care veti testa aceste metode. | + | } |
| + | </code> | ||
| - | === 2) Factory === | + | Clasele Hero și BadLuck sunt clase abstracte! |
| - | Modificati exercitiul anterior astfel: clasa **Product** va fi abstracta si va fi extinsa de urmatoarele clase, care vor diferi printr-o metoda **getPriceReduced** de tip float, care va returna pretul redus al unui produs, depinzand de categoria acestuia: | + | === Problema 2 - Decorator === |
| - | * Book (15\%) | + | |
| - | * Food (20\%) | + | |
| - | * Beverage (5\%) | + | |
| - | * Computer (10\%). | + | |
| - | Clasa prin care se vor crea obiectele de tip **Product** se va numi **ProductFactory** si va avea o metoda | + | |
| - | ** factory(String type, String nameProduct, float productPrice) ** | + | |
| - | care va returna un obiect de tip **Product**, construit cu **productName** si **productPrice**, in functie de tipul de produs dorit de utilizator, specificat prin parametrul **type**. | + | |
| - | === 3) Observer === | + | Folosind **design pattern-ul Decorator**, implementați clasele și interfețele necesare |
| - | Implementati un mini-sistem de notificare a utilizatorilor abonati la un canal Youtube. Veti implementa o clasa-subiect numita **Channel**, care va reprezenta un canal si o clasa-observator numita **User**, care va reprezenta un utilizator. | + | pentru a putea construi un obiect de tip **IceCream** ce conține două toppinguri: |
| - | Clasa **Channel** va contine o lista de utilizatori abonati la canalul respectiv, un membru de tip String ce va reprezenta numele canalului si urmatoarele metode: | + | **Chocolate** și **Vanilla**. Afișați prețul și descrierea acestei înghețate. |
| - | * void subscribe (User user) - se va adauga un utilizator in lista de abonati | + | |
| - | * void unsubscribe (User user) - se va sterge un utilizator din lista de abonati | + | |
| - | * void notify (String notification) - se va trimite o notificare (mesaj de tip String) tuturor utilizatorilor din lista de abonati (de exemplu ca s-a incarcat un nou videoclip pe canal) | + | |
| - | Testati clasele implementate intr-un main. | + | |
| - | === 4) Strategy === | + | În constructorul fiecărui topping, respectiv în constructorul **BasicIceCream** se va |
| + | afișa un mesaj prin care se specifică ce se adaugă. | ||
| - | Implementati un mini-sistem de calcul al pensiilor lunare in functie de anii de vechime si pe baza unui salariu lunar dat. Interfata **Strategy** va contine o metoda **calcul(int aniVechime, float salariu)** care returneaza un float. Veti avea de implementat clasele: | + | Prețuri: basicIceCream 0.5, ciocolată 1.5, vanilie 2. |
| - | * TwentyStrategy, care calculeaza pensia dupa formula aniVechime / 20 * salariu | + | |
| - | * ThirtyStrategy, cu pensia calculata dupa formula aniVechime / 30 * salariu | + | |
| - | * FortyStrategy, cu pensia calculata ca aniVechime / 40 * salariu. | + | |
| - | Creati o clasa numita Pensionar, care contine trei membri (int aniVechime, float salariu si Strategy strategy) si o metoda de tip float getPensie(), care va returna pensia calculata folosind strategiile enuntate anterior in urmatorul fel: | + | |
| - | * daca 20 <= aniVechime < 30, atunci se va folosi TwentyStrategy | + | |
| - | * daca 30 <= aniVechime < 40, atunci se va folosi ThirtyStrategy | + | |
| - | * daca 40 <= aniVechime, atunci se va folosi FortyStrategy | + | |
| - | Testati functionarea sistemului intr-un main. | + | |
| - | === 5) Visitor === | + | Descriere metode: |
| + | * **getDescription()**: returnează elementele componente ale înghețatei până acum (adică lista tuturor componentelor adăugate anterior plus topping-ul curent); | ||
| + | * **getPrice()**: returnează costul curent al înghețatei (suma tuturor elementelor adăugate anterior + costul toppingului curent). | ||
| - | Pornind de la exemplul prezentat in breviar la Visitor, implementati comenzile ls si cat pentru fisiere (clasele **Ls** si **Cat**). | + | <note important> |
| + | Pentru a putea adăuga funcționalitate (în cazul de față un topping) unui obiect, | ||
| + | vom avea nevoie de o referință către obiectul respectiv în decorator. | ||
| + | Un con (obiect de tipul BasicIceCream) fără topping este considerat tot o înghețată! | ||
| + | </note> | ||
| - | Clasele **Fisier** si **Director** mostenesc o clasa abstracta **Repository**, care este de tip **Visitable**, iar clasa **Director** contine o lista de **Repository**-uri, care reprezinta fisierele si folderele din folderul respectiv. | + | <note warning> |
| + | Pentru a putea adăuga topping-uri avem nevoie de un con! | ||
| + | </note> | ||
| - | Clasa **Director** va contine o metoda de tip void **addChild**(Repository rep), care va adauga un Repository in lista de Repository-uri din folder (aici puteti sa va folositi de clasa **File**, mai precis de una dintre metodele list(), care returneaza un array de String-uri de nume de fisiere si foldere din folderul curent, sau listFiles(), care returneaza o lista de obiecte de tip File (fisiere si foldere). | + | **Exemplu output:** |
| + | <code> | ||
| + | Adding cone | ||
| + | Adding choco | ||
| + | Adding vanilla | ||
| + | Ingrediente: cone, chocolate, vanilla | ||
| + | Cost: 4.0 | ||
| + | </code> | ||
| - | In clasa **Cat**, la visit(Fisier), veti folosi citirea din fisiere pentru a afisa continutul unui fisier. | + | === Problema 3 === |
| + | Definiți clasa GenericListMethods care să implementeze interfața, pusă la dispoziție | ||
| + | în arhiva laboratorului, GenericInterface. | ||
| - | <hidden> | + | Această interfață conține operații care prelucrează o listă, cu elemente de tip Comparable. |
| - | <HTML> | + | |
| - | <iframe src="https://ocw.cs.pub.ro/courses/_media/poo/laboratoare/lab12_var_final.pdf" width="640" height="720"></iframe> | + | |
| - | </HTML> | + | |
| - | <html> | + | * Metoda **removeDuplicates** primește ca parametru un obiect de tip ArrayList și transformă lista într-o mulțime, eliminând duplicatele. |
| - | <iframe src="https://ocw.cs.pub.ro/courses/_media/poo/laboratoare/poo_lab12_v1.pdf" width="640" height="720"></iframe> | + | * Metoda **max** are ca parametru tot un ArrayList și returnează elementul maxim din listă. |
| - | </html> | + | * Metoda **binarySearch** este folosită pentru a determina poziția unei valori într-o listă ordonată, utilizând pentru aceasta algoritmul de căutare binară, detaliat în blocul de cod de mai jos. |
| - | </hidden> | + | |
| - | <hidden> | + | <code java> |
| - | {{:poo:laboratoare:laborator12_schelet.zip|Schelet de laborator}} | + | int BinarySearch(v, start, end, x) { |
| + | // condiția de oprire (x nu se află în v) | ||
| + | if (start > end) | ||
| + | return -1; | ||
| + | |||
| + | // etapa divide | ||
| + | int mid = (start + end) / 2; | ||
| + | |||
| + | // etapa stăpânește | ||
| + | if (v[mid] == x) | ||
| + | return mid; | ||
| + | if (v[mid] > x) | ||
| + | return BinarySearch(v, start, mid - 1, x); | ||
| + | if (v[mid] < x) | ||
| + | return BinarySearch(v, mid + 1, end, x); | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | === Problema 4 === | ||
| + | |||
| + | Pornind de la clasa abstractă AMatrix, pusă la dispoziție în arhiva laboratorului, | ||
| + | implementați clasa IntegerMatrix care moștenește această clasă abstractă și modelează | ||
| + | un tablou bidimensional cu numere întregi. | ||
| + | |||
| + | Clasa AMatrix moștenește clasa ArrayList. Astfel, matricea propriu-zisă este un obiect | ||
| + | de tip ArrayList care conține elemente de tip ArrayList. | ||
| + | |||
| + | Clasa va conține metode pentru următoarele operații: afișarea matricei, adunarea a două | ||
| + | matrice, și metoda sum pentru a aduna două elemente! | ||
| + | |||
| + | <code java> | ||
| + | // afișare | ||
| + | public String toString(); | ||
| + | |||
| + | // sum | ||
| + | public Integer sum(Integer obj1, Integer obj2); | ||
| + | |||
| + | // adunare | ||
| + | public AMatrix addition(AMatrix m); | ||
| + | </code> | ||
| + | |||
| + | Folosiți iteratori pentru parcurgerea colecțiilor sau bucle for each! | ||
| + | |||
| + | === Problema 5 === | ||
| + | |||
| + | Să se definească o clasă generică ArrayMap, pentru un dicționar realizat din doi vectori | ||
| + | (un vector de chei și un vector de valori asociate, obiecte din clasa Vector), care să | ||
| + | poată înlocui o clasă HashMap sau TreeMap. | ||
| + | |||
| + | Astfel, această clasă va extinde clasa AbstractMap, suprascriind următoarele metode: | ||
| + | |||
| + | <code java> | ||
| + | public String toString(); | ||
| + | public V put(K, V); | ||
| + | public V get(Object); | ||
| + | public Set<K> keySet(); | ||
| + | public Collection<V> values(); | ||
| + | public Set<Map.Entry<K, V>> entrySet(); | ||
| + | // atenție! Se va defini o clasă internă pentru o intrare în dicționar - Map.Entry | ||
| + | </code> | ||
| + | |||
| + | Afișați dicționarul folosind System.out.println(dictionar) și apoi folosind un Iterator | ||
| + | pentru a parcurge mulțimea intrărilor generată de metoda entrySet. | ||
| - | Scopul vostru este să dezvoltați o aplicație care ajută elevii din clasa a 3-a să rezolve expresii artimetice. Aplicația voastră va primi ca input un String ce conține o expresie și va arăta elevului pas cu pas cum se rezolvă expresia. Această aplicație se va numi "Arithmo". Formatul expresiilor de input va fi: **(operand operator operand)** unde operatorul poate fi ''*,/,-,+'' iar operanzii pot fi valori numerice sau alte expresii. Un posibl input poate fi ''(2 + ( (9 / 3) * ( (5 * 2) - (6 * 1))))''. Evolutia expresiei va fi: ''(2 + (3 * (10 - 6))) -> (2 + (3 * 4)) -> (2 + 12) -> 14''.</hidden> | ||