Laboratorul 11.

Problema 1 - Singleton

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.

public class Catalog {
       // TODO -- Adaugati aici implementarea exercitiului
}
public class Course {
}

Problema 2 - Factory

Pornind de la clasa abstracta User, definiți clasele Student, Parent, Assistant și Teacher care vor moșteni clasa User:

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;
  }
}

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).

Pentru testare folositi clasa Test de mai jos, in care veti comenta cerintele neimplementate inca:

class Test {
    public static void main(String[] args) {
        //testare exercitiu 2
        User studentA = UserFactory.createUser("Student", "A", "Popescu");
        User studentB = UserFactory.createUser("Student", "B", "Ionescu");
        User studentC = UserFactory.createUser("Student", "C", "Ionescu");
 
        User mother = UserFactory.createUser("Parent", "M_AC", "Ionescu");
        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<Assistant, ArrayList<Pair<Student, String, 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);
 
    }
}

Problema 3 - Builder

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.

Pentru a putea seta câmpurile unui obiect de tip Course, veți folosi șablonul de proiectare Builder. ! Definiti toString pentru clasa Course.

public class Grade {
private Double partialScore, examScore;
private Student student;
private String course;
 
public Grade(String course, Student student) {
        partialScore = 0.0;
        examScore = 0.0;
        this.course = course;
        this.student = student; 
    	}
 
public Grade(String course, Student student,Double partialScore, Double examScore ) {
        this.partialScore = partialScore;
        this.examScore = examScore;
        this.course = course;
        this.student = student; 
    	}
 
public void setPartialScore(Double score) {
     partialScore = score;
}
public void setExamScore(Double score) {
     examScore = score;
}
public Double getTotal() {
      return partialScore + examScore;
}
}

Modificați clasa Grade astfel încât doua obiecte de tip Grade vor putea sa fie comparate (în funcție de punctajul total). De asemenea, va trebui sa adaugați în clasa Catalog o lista cu obiecte de tip Course.

Folositi pentru testare main-ul de la Factory!

Problema 4 - Observer

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. Pentru a putea realiza acest lucru, veț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).

Ce clasa va implementa interfața Observer și ce clasa va implementa interfața Subject?

public interface Observer {
    void update(Notification notification);
}
 
public interface Subject {
   void addObserver(Observer observer);
   void removeObserver(Observer observer);
   void notifyObservers(Grade grade);
}

Hint!

1.Parent va tine minte si o lista a notificarilor, iar Catalog o lista a Observatorilor.

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.

Folositi pentru testare main-ul de la Factory!

Problema 5 - Strategy

Fiecare profesor va aplica o politica prin care la sfârșitul semestrului selecteaza cel mai bun student. Pentru 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. 1. BestPartialScore – aceasta strategie va selecta studentul care are cel mai mare punctaj în timpul semestrului;
  2. 2. BestExamScore – aceasta strategie va selecta studentul care are cel mai mare punctaj în examen;
  3. 3. BestTotalScore – aceasta strategie va selecta studentul care are punctajul total maxim.
interface Strategy {
    Student getBestStudent(Collection<Grade> grades);
}

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.

Folositi pentru testare main-ul de la Factory!

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.

public interface Element {
  void accept(Visitor visitor);
}
public interface Visitor {
  void visit(Assistant assistant);
  void visit(Teacher teacher);
}

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:

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**
  }
}

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.

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.

Folositi pentru testare main-ul de la Factory!

poo/laboratoare/13.txt · Last modified: 2023/12/09 11:42 by carmen.odubasteanu
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