Differences

This shows you the differences between two versions of the page.

Link to this comparison view

poo:laboratoare:13 [2019/01/11 13:18]
mihai.nan
poo:laboratoare:13 [2023/12/09 11:42] (current)
carmen.odubasteanu
Line 1: Line 1:
-===== Laboratorul ​13. =====+===== Laboratorul ​11. =====
  
-=== Problema 1 === +=== Problema 1 - Singleton  ​===
-Pornind de la diagrama data, implementati clasele si interfetele din diagrama si cele care mai sunt necesare pentru a putea  apoi sa construiti un obiect de tip **//​IceCream//​** ce contine doua toppinguri: **//​Chocolate//​** si **//​Vanilla//​**. Afisati pretul si descrierea acestei inghetate (design pattern-ul Decorator)+
  
-In constructorul fiecarui topping, respectiv in constructorul ​**//​BasicIceCream//​** se va afisa un mesaj prin care se specifica ce se adauga.+Implementați o clasa **Catalog** care conține o lista cu obiecte de tip **Course**.  
 +Va trebui sa va asigurați ca pentru aceasta clasa va putea exista o singura instanța ​care sa poata fi accesata din orice clasa a proiectului. Implementati metoda **toString** pentru clasa **Catalog**.
  
-Preturi: basicIceCream 0.5, ciocolata 1.5, vanilie 2.+<code java> 
 +public class Catalog { 
 +       // TODO -- Adaugati aici implementarea exercitiului 
 +
 +public class Course { 
 +
 +</​code>​
  
-Descriere metode: +=== Problema 2 - Factory === 
-  * **getDescription()**: returneaza elementele componente ale inghetatei pana acum(adica lista tuturor componentelor adaugate anterior plus topping-ul curent); +Pornind de la clasa abstracta ​**User**, definiți clasele **Student**,​ **Parent**, **Assistant** și **Teacher** care vor moșteni clasa **User**:
-  ​* **getPrice()**: returneaza costul curent al inghetatei(suma tuturor elementelor adaugate anterior + costul toppingului curent).+
  
-{{:​poo:​laboratoare:​uml.png?600|}}+<code java> 
 +public abstract class User { 
 +  protected String firstName, lastName; 
 +  public User(String firstName, String lastName) ​{ 
 +    this.firstName = firstName;​ 
 +    this.lastName = lastName; 
 +  } 
 +  public String toString() { 
 +    return firstName + " " + lastName; 
 +  ​} 
 +} 
 +</​code>​
  
 +Pentru a putea realiza o instanțiere ușoara a obiectelor pentru aceste tipuri de clase, veți implementa o clasa **UserFactory** care va avea o metoda __statica__ **createUser** ce va returna un obiect de tip **User** (se va folosi șablonul de proiectare **Factory**).
  
-<note important>Pentru a putea adauga functionalitate ​(in cazul de fata un toppingunui obiectvom avea nevoie de o referinta catre obiectul respectiv in decorator.  +Pentru testare folositi clasa **Test** de mai jos, in care veti comenta cerintele neimplementate inca: 
-Un con (obiect de tipul BasicIceCreamfara topping este considerat tot o inghetata!<​/note> + 
-<note warning> +<code java> 
-Pentru a putea adauga topping-uri avem nevoie de un con! +class Test { 
-</note> +    public static void main(String[] args
-//**Exemplu output:**// +        //testare exercitiu 2 
-<code+        User studentA = UserFactory.createUser("​Student"​"​A",​ "​Popescu"​);​ 
-Adding cone +        User studentB = UserFactory.createUser("​Student",​ "​B",​ "​Ionescu"​);​ 
-Adding choco +        User studentC = UserFactory.createUser("​Student",​ "​C",​ "​Ionescu"​)
-Adding vanilla + 
-Ingrediente:​ conechocolatevanilla +        User mother = UserFactory.createUser("​Parent",​ "​M_AC",​ "​Ionescu"​);​ 
-Cost: 4.0+        User father = UserFactory.createUser("​Parent",​ "​T_AC",​ "​Ionescu"​);​ 
 +        
 +        User teacher = UserFactory.createUser("​Teacher",​ "​Teacher",​ "​Georgescu"​);​ 
 +        User assistant = UserFactory.createUser("​Assistant",​ "​Assistant",​ "​Popescu"​);​ 
 +         
 +        ​//testare exercitiu 3+5 
 +        ​Course course = new Course.CourseBuilder("​POO"​).teacher((Teacher) teacher) 
 +       .assistant((Assistant) assistant).grade(new Grade("​POO",​ (Student) studentA, 4d,5d)) 
 +       .grade(new Grade("​POO",​ (Student) studentB,​3d,​3d)).strategy(new BestExamScore()).build();​ 
 +         
 +        System.out.println("​Curs:​ "+ course); 
 +        System.out.println("​Best Student:"​ + course.getBestStudent());​ 
 +         
 +        ​//testare exercitiu 1+3+5 
 +        ​Catalog catalog = Catalog.getInstance();​ 
 +        catalog.addCourse(course);​ 
 +          
 +        ​//testare exercitiu 4 
 +        ((Student) studentB).setMother((Parent) mother); 
 +        ((Student) studentB).setFather((Parent) father); 
 +        ((Student) studentC).setMother((Parent) mother); 
 + 
 +        catalog.addObserver((Parent) mother); 
 +        catalog.addObserver((Parent) father); 
 +        catalog.notifyObservers(new Grade("​POO",​ (Student)studentB,​2.5d,​3d));​ 
 +         
 +        ​//testare exercitiu 6 
 +        ​HashMap<Teacher, ArrayList<​Pair<​Student,​ String, Double>>> examScores=new HashMap<>​();​ 
 +        ​ArrayList<​Pair<​Student,​ String, Double>>​ ar1=new ArrayList<>​();​ 
 +        ​ar1.add(new Pair(studentA,"​POO",​3.6d));​ 
 +        ​examScores.put((Teacher)teacher,​ar1);​ 
 +         
 +        HashMap<​AssistantArrayList<​Pair<​StudentString, Double>>>​ partialScores= new HashMap<>​();​ 
 +        ​ArrayList<​Pair<​Student,​ String, Double>>​ ar2=new ArrayList<>​();​ 
 +        ar2.add(new Pair(studentC,"​POO",​4.6d)); 
 +        partialScores.put((Assistant)assistant,​ar2);​ 
 +     
 +       ​Visitor v=new ScoreVisitor(examScores,​partialScores);​ 
 +        
 +        v.visit((Teacher)teacher);​ 
 +        System.out.println("​Actualizare teacher:"​ + catalog); 
 +                 
 +        v.visit((Assistant)assistant);​ 
 +        System.out.println("​Actualizare assistant:"​ + catalog); 
 +        
 +    } 
 +}
 </​code>​ </​code>​
  
-=== Problema ​=== +=== Problema ​3 - Builder ​===
-Realizați o arhitectură unificată, similară cu Collections,​ pentru manipularea listelor care să conțină:​ +
-  * interfața //​**Function**//,​ parametrizată corespunzător,​ care conține o metodă //​**execute**//,​ având ca parametru un obiect de tip //**A**// și un rezultat de tip //**B**//, unde //**A**// și //**B**// sunt două tipuri formale; +
-  * interfața //​**Addition**//​ folosită pentru a calcula suma a două numere de tip //**T**//, unde //**T**// este un subtip al lui //​**Number**//​ (aceasta va conține o metodă //​**zero**//​ care va întoarce elementul neutru al operației de adunare și o metodă //​**add**//,​ care primește două obiecte de tip //**T**// și returnează suma lor); +
-  * doi algoritmi polimorfici:​ //​**reverse**//​ care inversează elementele unei liste și //**sum**// care calculează suma elementelor din listă; acești algoritmi trebuie să poată fi folosiți pe implementări diferite de liste, deoarece le abordează la nivel de interfață;​ +
-  * o serie de metode care au un comportament similar cu funcționalele din paradigma funcțională. În cadrul acestei paradigme, funcțiile sunt valori de ordinul 1 ce pot fi manipulate ca orice altă valoare, iar funcționalele sunt funcții care manipulează alte funcții, primindu-le ca argumente sau returnându-le ca rezultat, în functie de cum e nevoie, fiind foarte utile în aplicarea anumitor modele de calcul des folosite.+
  
-Veți porni implementarea de la clasa **//​ListUtil//​**, pusă la dispoziție în arhiva laboratorului.+Pe baza claselor definite anterior, veți completa ​implementarea ​clasei **Course**. În cadrul aplicației ​ noastre, un obiect ​de tipul **Course** o sa conțina: un nume (de tipul **String**)un profesor titular, o lista de asistenți, o colecție ordonata cu obiecte de tipul **Grade** și o lista de studenți
  
-Explicatii ​pentru ​functionale:​+Pentru a putea seta câmpurile unui obiect de tip **Course**, veți folosi șablonul de proiectare **Builder**. 
 +! Definiti **toString** ​pentru ​clasa **Course**.
  
--**foldl**(functioninit, list)- returnează rezultatul aplicării functiei function pe rând asupra unui element din listă si a unui acumulator init. Ordinea folosirii elementelor din listă este de la stânga la dreapta+<code java> 
-Exemplu: +public class Grade { 
-foldl(f(x, y) = x + y, 5, [0, 1, 2, 3]) => 11 +private Double partialScoreexamScore
 +private Student student; 
 +private String course;
  
--**foldr**(functioninit, list)- are un comportament similar cu foldl, însă ordinea folosirii elementelor din listă este de la dreapta la stânga+public Grade(String courseStudent student
-Exemplu: +        partialScore = 0.0
-foldr(f(x, y) y, 4, [0, 1, 2, 3]) => 0+        ​examScore ​= 0.0; 
 +        this.course ​course; 
 +        this.student = student;  
 +    }
  
--**map**(functionlist)- returnează lista rezultatelor aplicării unei functii f asupra fiecărui element dintr-o listă+public Grade(String courseStudent student,​Double partialScore,​ Double examScore ​
-Exemplu: +        this.partialScore = partialScore
-map(f(x) ​2*x,[0, 1, 2, 3]) => [0, 2, 4, 6]+        ​this.examScore = examScore; 
 +        ​this.course ​course; 
 +        this.student ​student;  
 +    }
  
--**filter**(predicat, list)- returnează lista elementelor dintr-o listă care satisfac un predicat p (un predicat îl vom percepe ca o functie care are un rezultat de tip Boolean); +public void setPartialScore(Double score
-Exemplu: +     ​partialScore = score; 
-filter(f(x= x % 2 == 0, P[0, 1, 2, 3]) =[0, 2]+
 +public void setExamScore(Double score
 +     ​examScore = score
 +} 
 +public Double getTotal() 
 +      return partialScore + examScore;​ 
 +
 +
 +</code>
  
--**reduce**(function, list)- aplică functia pentru primele două elemente din lista, apoi pentru rezultatul obtinut anterior si urmatorul element si tot asa; +Modificați clasa **Grade** astfel încât doua obiecte de tip **Grade** vor putea sa fie comparate ​(în funcție de punctajul total) 
-Exemplu: +De asemeneava trebui sa adaugați în clasa **Catalog** o lista cu obiecte de tip **Course**.
-reduce(f(xy) = x + y, [47, 11, 42, 13]) => 113+
  
--**all**(predicat,​ list)- primeste un predicat (metoda ce are ca rezultat un boolean) si verifică dacă toate elementele din listă satisfac predicatul;​ +<​note>​ Folositi pentru testare main-ul de la Factory! </note
-Exemplu: +
-all(f(x) = x > 0, [0, 1, 2, 3]) => True ;  +
-all(f(x) = x % 2 == 0, [0, 1, 2, 3]) =False+
  
--**any**(predicat, list)- primeste ​un predicat si verifică dacă exista cel putin un element în lista care satisface predicatul+=== Problema 4 Observer === 
-Exemplu: +Aplicația noastra le permite parinților unui student sa se aboneze la **Catalog** pentru a putea primi notificari în momentul în care copilul este notat de catre un profesor sau de catre un asistent
-any(f(x) = x < 0,[1, 2, 3, 4]) => False ; +Pentru a putea realiza acest lucruveți folosi șablonul de proiectare **Observer** și veți implementa o clasa  **Notification ** (stabiliți voi care sunt atributele și metodele din aceasta clasa – este obligatoriu sa fie suprascrisa metoda **toString**).
-any(f(x= x % 2 == 0,[1, 2, 3]) => True+
  
-Pentru testare, completati exemplele din clasa Test.+Ce clasa va implementa interfața **Observer** și ce clasa va implementa interfața **Subject**?​
  
-<HTML+<code java
-  <​iframe src="​https://​ocw.cs.pub.ro/​courses/​_media/​poo/​laboratoare/​laborator_13.pdf"​ width="​740"​ height="​720"></​iframe>​ +public interface Observer { 
-</​HTML>​+    void update(Notification notification);​ 
 +}
  
 +public interface Subject {
 +   void addObserver(Observer observer);
 +   void removeObserver(Observer observer);
 +   void notifyObservers(Grade grade);
 +}
 +</​code>​
  
-=== Problema 3 === +<​note>​ 
-Sa se scrie un program pentru afisarea pe ecran a liniilor aflate pe pozitii impare dintr-un fisier text. Fiecare linie va fi precedata de numarul ei si un spatiu. In implementare,​ se va folosi un obiect de tip //​**LineNumberReader**//​. Tratati toate exceptiile care ar putea sa apara exact acolo unde apar! Atentie la inchiderea fisierelor – sa se faca chiar daca apare exceptie la citire!+Hint
  
-Pentru validarea acestei cerinte, puteti folosi fisierul text //test01.in// pus la dispozitie in arhiva laboratorului.+1.Parent va tine minte si o lista a notificarilor,​ iar Catalog o lista a Observatorilor.
  
-=== Problema ​=== +2. Atentie! Primesc notificari doar parintii studentului respectiv! Modificati clasa Student astfel incat sa avem memorati si parintii pentru fiecare Student si adaugati o metoda isParent(Observer parent) care verifica daca un observator este parintele studentului current. 
-Sa se scrie un program ​care citeste un text de la tastura si il salveaza intr-un fisier pe discCitirea se va face pana la introducerea cuvantului //**exit**//In implementare se va uzita metoda //**readLine()**// pentru un obiect de tip //**DataInputStream**// sau //**BufferedReader**//Tratati toate exceptiile care ar putea sa apara!+</​note>​ 
 +<​note>​ Folositi pentru testare main-ul de la Factory! </​note>​  
 + 
 +=== Problema ​5 - Strategy ​=== 
 + 
 +Fiecare profesor va aplica o politica prin care la sfârșitul semestrului selecteaza cel mai bun studentPentru a realiza acest lucru în cadrul implementarii, ​va trebui sa folosiți șablonul de proiectare ​**Strategy**. Veți defini câte o clasa pentru fiecare din urmatoarele strategii:​ 
 + 
 +  - 1. **BestPartialScore** – aceasta strategie va selecta studentul care are cel mai mare punctaj în timpul semestrului;​ 
 +  - 2. **BestExamScore** – aceasta strategie va selecta studentul care are cel mai mare punctaj în examen; 
 +  - 3. **BestTotalScore** – aceasta strategie va selecta studentul care are punctajul total maxim.
  
-=== Problema 5 === 
-Sa se implementeze un program care citeste din fisierul //​test02.in//​ un text si determina numarul de cuvinte din text. Pentru citire se vor utiliza un obiect de tip //​**FileReader**//​ si unul de tip //​**StreamTokenizer**//​. 
 <code java> <code java>
-FileReader in = new FileReader(new File("​test02.in"​)); +interface Strategy { 
-StreamTokenizer str = new StreamTokenizer(in);​+    Student getBestStudent(Collection<​Grade>​ grades); 
 +}
 </​code>​ </​code>​
  
-{{:​poo:​laboratoare:​arhiva_13.zip|Arhiva laborator}}+Veți adauga în clasa **Course** un atribut **Strategy**,​ si o metoda cu antetul: 
 +public Student **getBestStudent**();​ 
 +Metoda va returna cel mai bun student, tinand cont de strategia setata ​ de profesor pentru curs. 
 + 
 +<​note>​ Folositi pentru testare main-ul de la **Factory**! </​note>​  
 + 
 +=== Problema 6 - Visitor === 
 + 
 +Folosind șablonul de proiectare **Visitor**,​ vom implementa funcționalitatea prin care fiecare asistent o sa poata completa notele de pe parcurs ale studenților,​ iar fiecare profesor o sa poata completa notele de la examen ale studenților sai.  
 +Pentru acest lucru, vom porni de la urmatoarele 2 interfețe: **Element** și **Visitor**. 
 +<code java> 
 +public interface Element { 
 +  void accept(Visitor visitor); 
 +
 +public interface Visitor { 
 +  void visit(Assistant assistant);​ 
 +  void visit(Teacher teacher); 
 +
 +</​code>​ 
 +Clasele **Assistant** și **Teacher** vor implementa interfața **Element**,​ iar clasa **ScoreVisitor** va implementa interfața **Visitor**.  
 +În clasa **ScoreVisitor** vom avea doua dicționare în care sunt stocate notele studentilor pentru examene și pentru parcurs. 
 +- Dicționarul **examScores** va avea cheia de tip **Teacher** și valoare de tip lista de **Pair** **(Student, Numele ​ cursului – ca String, nota pe care a acordat-o studentului pentru cursul indicat – ca Double).** 
 +- Dicționarul **partialScores** cu semnificație similara, dar pentru notele de pe parcurs atribuite de asistenți. 
 + 
 +În continuare, se va prezenta implementarea de la care veți porni pentru aceasta clasa: 
 + 
 +<code java> 
 +class Pair<K, V1, V2> { 
 +  private K key; 
 +  private V1 value1; 
 +  private V2 value2; 
 +  public Pair(K key, V1 value1, V2 value2) { 
 +    this.key = key; 
 +    this.value1 = value1; 
 +    this.value2 = value2; 
 + } 
 + ​public K getKey() { 
 +   ​return key; 
 + } 
 + ​public V1 getValue1() { 
 +  return value1; 
 + } 
 + ​public V2 getValue2() { 
 +  return value2; 
 + } 
 +
 +public class ScoreVisitor implements Visitor { 
 +  private HashMap<​Teacher,​ ArrayList<​Pair<​Student,​ String, Double>>>​ examScores;​ 
 +  private HashMap<​Assistant,​ ArrayList<​Pair<​Student,​ String, Double>>>​ partialScores;​ 
 +  public ScoreVisitor(HashMap<​Teacher,​ ArrayList<​Pair<​Student,​ String, Double>>>​ examScores, HashMap<​Assistant,​ ArrayList<​Pair<​Student,​ String, Double>>>​ partialScores){ 
 +       ​this.examScores=examScores;​ 
 +       ​this.partialScores=partialScores;​ 
 +  } 
 +  public void visit(Assistant assistant) { 
 +   // **TODO1** 
 +  } 
 +  public void visit(Teacher teacher) { 
 +   // **TODO2** 
 +  } 
 +
 +</​code>​ 
 + 
 +• **TODO1** – veți determina toate notele pe care le are de trecut asistentul primit ca parametru de metoda respectiva. Veți verifica daca pentru o intrare din lista de note exista sau nu un obiect de tip **Grade** pentru cursul indicat corespunzator studentului. 
 +Daca exista, atunci se va seta nota de pe parcurs pentru acel obiect, daca nu exista, se va crea un nou obiect **Grade** și se va adauga cursului. 
 + 
 +• **TODO2** – veți determina toate notele pe care le are de trecut profesorul primit ca parametru de metoda respectiva. Veți verifica daca pentru o intrare din lista de note exista sau nu un obiect de tip **Grade** pentru cursul indicat corespunzator studentului. 
 +Daca exista, atunci se va seta nota de la examen pentru acel obiect, daca nu exista, se va crea un nou obiect **Grade** și se va adauga cursului. 
 + 
 +<​note>​**Hint!** 
 +Veti adauga metodele de care aveti nevoie in clasele utilizate.  
 + 
 +Exemple: 
 +In **Catalog** veti adauga o metoda public **Course** **getCourse**(**String** name), care intoarce obiectul Course corespunzator numelui trimis ca parametru. 
 + 
 +In **Course** o metoda **addGrade**(**Grade** g); 
 +Etc. 
 +</​note>​ 
 + 
 +<​note>​ Folositi pentru testare main-ul de la **Factory**! </​note>​  
 +<​hidden>​{{:​poo:​laboratoare:​arhiva_13.zip|Arhiva laborator}} 
 +</​hidden>​
  
poo/laboratoare/13.1547205539.txt.gz · Last modified: 2019/01/11 13:18 by mihai.nan
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0