Differences

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

Link to this comparison view

poo-ca-cd:laboratoare:visitor [2022/11/21 00:20]
diana.tatulescu [Summary]
poo-ca-cd:laboratoare:visitor [2023/11/19 14:55] (current)
aconstantinescu1704
Line 9: Line 9:
   * Prezentarea design pattern-ului Visitor și familiarizarea cu situațiile în care acesta este util de aplicat   * Prezentarea design pattern-ului Visitor și familiarizarea cu situațiile în care acesta este util de aplicat
  
 +==== Polimorfismul ====
  
 +**Polimorfismul reprezintă abilitatea unei clase să se comporte ca o altă clasă de pe lanțul de moștenire, și de aceea conceptul de suprascriere a metodelor este foarte strâns legat.**
 +
 +Mai precis, polimorfismul permite obiectelor de tipuri diferite să fie tratate folosind o interfață comună sau o clasă de bază.
 +Există două tipuri principale de polimorfism în POO: polimorfismul prin suprascrierea metodelor (override) și polimorfismul prin supraincarcarea metodelor (overloading).
  
 ==== Overriding ==== ==== Overriding ====
Line 27: Line 32:
 Din acest motiv, suprascrierea este cunoscută și ca **polimorfism dinamic** (__Runtime polymorphism__). ​ Din acest motiv, suprascrierea este cunoscută și ca **polimorfism dinamic** (__Runtime polymorphism__). ​
  
-**Polimorfismul reprezintă abilitatea unei clase să se comporte ca o altă clasă de pe lanțul de moștenire, și de aceea conceptul de suprascriere a metodelor este foarte strâns legat.** 
    
-<note important>​ La apelarea unei metode suprascrise,​ Java se uită la tipul intern al obiectului pentru care este apelată metoda, NU la referință. Astfel dacă referința are tipul clasei părinte, dar tipul este al clasei copil, JVM va apela metoda din clasa copil. </​note>​+<note important>​ La apelarea unei metode suprascrise,​ Java se uită la tipul intern al obiectului pentru care este apelată metoda, NU la referință. Astfel dacă referința are tipul clasei părinte, dar tipul obiectului ​este al clasei copil, JVM va apela metoda din clasa copil. </​note>​
    
 Câteva **reguli pentru suprascriere** sunt: Câteva **reguli pentru suprascriere** sunt:
Line 108: Line 112:
 </​note>​ </​note>​
    
-=== super === 
-  
-În laboratorul [[:​poo-ca-cd:​laboratoare:​agregare-mostenire#​cuvantul_cheie_super_intrebuintari| de agregare și de moștenire]] am folosit cuvântul cheie **super** pentru a invoca un anumit constructor din clasa părinte dar și pentru a apela în mod explicit metoda din clasa părinte în cazul metodelor suprascrise. 
-  
-Rescriem metoda ''​purr()''​ din clasa ''​GrumpyCat''​ astfel: 
-<code java> 
-@Override 
-public void purr() { 
-    super.purr();​ 
-    System.out.println("​NO!"​);​ 
-} 
-</​code>​ 
-La apelul metodei pe o instanță a clasei ''​GrumpyCat''​ output-ul va fi: 
-<​code>​ 
-purrrr 
-NO! 
-</​code>​ 
- 
- 
  
 ==== Overloading ==== ==== Overloading ====
Line 205: Line 190:
 Pattern-ul **Visitor** este util când: Pattern-ul **Visitor** este util când:
   * se doreşte prelucrarea unei //structuri complexe//, ce cuprinde mai multe obiecte de //tipuri diferite//   * se doreşte prelucrarea unei //structuri complexe//, ce cuprinde mai multe obiecte de //tipuri diferite//
-  * se doreşte definirea de //operaţii distincte pe aceeaşi structură//pentru ​preveni poluarea ​interfeţelor claselor implicate, cu multe detalii ​aparţinând unor algoritmi diferiţiÎn acest fel, se centralizează ​aspectele legate de acelaşi algoritm //într-un singur loc//, dar, în acelaşi timp, //se separă ​detaliile ​ce ţin de algoritmi diferiţi//​. Acest lucru conduce la simplificarea atât a claselor prelucrate, cât şi a vizitatorilor. Orice date specifice ​algoritmului rezidă ​în vizitator+  * se dorește definirea de operații specifice pentru ​aceeași structură, ​fără ​polua interfeţele claselor implicate, cu multe detalii ​specifice algoritmilorVizitatorul ​centralizează ​logica comunăpăstrând ​în același timp detaliile specifice în interiorul acestuia
-  * ** clasele ce se doresc prelucrate se modifică rar, în timp ce operaţiile de prelucrare se definesc des**. ​Dacă însă sunt introduse multe clase visitabile, după crearea obiectelor Visitor, atunci este necesară modificarea ​acestora din urmă, pentru adăugarea de metode //visit// pentru noile clase.+  * ** clasele ce se doresc prelucrate se modifică rar, în timp ce operaţiile de prelucrare se definesc des**. ​Vizitatorul permite adăugarea de noi funcționalități fără modificarea ​claselor existente. 
 === Structură ===  === Structură === 
  
 {{ .:​visitor:​visitor.png?​680 | Componente pattern Visitor }} {{ .:​visitor:​visitor.png?​680 | Componente pattern Visitor }}
  
-**Visitor** - o interfață pentru operația aplicată  +Structura design pattern-ului "Visitor" este formată din următoarele componente:
-**Visitable** - o interfață pentru obiecte pe care pot fi aplicate operațiile (în diagramă este numită ''​Element''​) +
-   * metoda ''​accept''​ e independentă de tipul concret al Visitor-ului +
-   * în ''​accept''​ se folosește obiectul de tip Visitor ​ +
-Pentru fiecare algoritm/​operație ce trebuie aplicată, se implementează clase de tip Visitor. În fiecare obiect de tip //Visitor// trebuie să implementăm metode care aplică operația pentru fiecare tip de element vizitabil.+
  
-<note tip>În imaginea de mai jos este reprezentat ​**flow-ul aplicării acestui pattern**: +**Client:** 
-   ​Clientul este cel care folosește o colecție ​de obiecte de unul sau mai multe tipuri, ​și dorește ​să aplice pe acestea diferite operații (în exercițiile din laborator clientul este practic programul vostru de test - main-ul). Clientul folosește obiecte //Visitor// create ​pentru ​fiecare operație necesară. +   * Este clasa consumatoare a design pattern-ului "​Visitor"​. 
-  - Clientul parcurge colecția și în loc să aplice operaţia direct pe fiecare obiect ​de tip //​Element//,​ îi oferă acestuia un obiect de tip //​Visitor//​.  +   * Are acces la obiectele din structura ​de date și poate instrui aceste obiecte ​să accepte un "Visitor" ​pentru ​a realiza prelucrările corespunzătoare
-  ​Obiectul de tip //Element// apelează metoda ​de "​vizitare"​ oferită de //Visitor//. +   * Exemplu: O aplicație care procesează diferite tipuri ​de elemente într-o structură de date complexă.
-  - Pe obiectul //Visitor// se apelează metoda //visit// corespunzătoare obiectului, iar în ea se efectuează operația. (:!: ** în Visitor folosim conceptul de //​overloading//​ pentru fiecare metodă //​visit//​**)  +
-</​note>​+
  
-{{ .:visitor:visitor-flow.png |Interacțiunile dintre componentele ​pattern-ului Visitor }}+**Visitor:​** 
 +   * Este o interfață sau o clasă abstractă folosită pentru a declara operațiile de vizitare pentru toate tipurile de clase vizitabile. 
 +   * Conține metode de vizitare corespunzătoare fiecărui tip de clasă vizitabilă. 
 +   * ExempluInterfața Visitor cu metodele visit(ElementA elementA), visit(ElementB elementB), etc. 
 + 
 +**ConcreteVisitor:** 
 +   * Pentru fiecare tip de "​Visitor",​ toate metodele de vizitare definite în "​Visitor"​ trebuie implementate. 
 +   * Fiecare "​Visitor"​ este responsabil pentru diferite operații. 
 +   * Exemplu: Clasa ConcreteVisitorA implementând interfața Visitor cu metodele sale specifice pentru tratarea diferitelor tipuri de elemente. 
 + 
 +**Visitable:​** 
 +   * Este o interfață pentru obiecte pe care pot fi aplicate operațiile 
 +   * Această operație permite unui obiect să fie "​vizitat"​ de către un obiect "​Visitor"​. 
 +   * Exemplu: Interfața Visitable cu metoda accept(Visitor ​visitor). 
 + 
 +**ConcreteVisitable:​** 
 +   * Aceste clase implementează interfața Visitable sau clasa și definesc operația accept. 
 +   * Prin intermediul acestei operații, obiectul "​Vizitabil"​ primește un obiect "​Visitor"​. 
 +   * Exemplu: Clasele ConcreteElementA,​ ConcreteElementB,​ etc., care implementează interfața Visitable și definesc metoda accept. 
 + 
 + 
 +<note tip> Flowul aplicării acestui ​pattern
 +  ​ Când un client dorește să efectueze operații pe obiectele vizitabile, el creează un obiect vizitator corespunzător,​ le "​vizitează"​ apelând metoda accept, iar fiecare obiect vizitabil interacționează cu vizitatorul prin intermediul metodelor visit. 
 +  -  Acest pattern oferă o modalitate de a separa algoritmii de obiectele pe care operează, facilitând extinderea și adăugarea de noi operații fără a modifica clasele obiectelor vizitabile. 
 +</​note>​
  
 <note important>​ <note important>​
Line 313: Line 317:
   * în cazul în care nu avem acces la codul claselor, singura modalitate de adăugare de funcţionalitate este extinderea   * în cazul în care nu avem acces la codul claselor, singura modalitate de adăugare de funcţionalitate este extinderea
  
-În final, tragem concluzia că este de dorit să **izolăm algoritmii de clasele pe care le prelucrează**. ​O primă idee se referă la utilizarea //metodelor statice//. Dezavantajul acestora este că nu pot reţine, într-un mod elegant, informaţie de stare din timpul prelucrării. De exemplu, dacă structura noastră ar fi arborescentă (recursivă),​ în sensul că o instanţă //Manager// ar putea ţine referinţe la alte instanţe //​Manager//,​ ce reprezintă şefii ierarhic inferiori, o funcţie de prelucrare ar trebui să menţină o informaţie parţială de stare (precum suma procentelor calculate până într-un anumit moment) sub forma unor parametri furnizaţi apelului recursiv: +În final, tragem concluzia că este de dorit să **izolăm algoritmii de clasele pe care le prelucrează**.
-<code java> +
-class Manager extends Employee { +
-        ... +
-        public float getPercentage(float sum, int n) { +
-                float f = bonus / getTotalRevenue();​ +
-                if (f > 0) +
-                        return inferiorManager.getPercentage(sum + f, n + 1); // trimite mai departe cererea catre nivelul inferior ​                +
-                return inferiorManager.getPercentage(sum,​ n); +
-        }         +
-+
-</​code>​+
  
-O abordare ​mai bună ar fi:+O abordare bună ar fi:
   * conceperea claselor cu **posibilitatea de primire/​ataşare a unor obiecte-algoritm**,​ care definesc operaţiile dorite   * conceperea claselor cu **posibilitatea de primire/​ataşare a unor obiecte-algoritm**,​ care definesc operaţiile dorite
   * definirea unor **clase algoritm** care vor __//​**vizita**//​__ structura noastră de date, vor //efectua// prelucrările specifice fiecărei clase, având, totodată, //​posibilitatea de încapsulare a unor informaţii de stare// (cum sunt suma şi numărul din exemplul anterior)   * definirea unor **clase algoritm** care vor __//​**vizita**//​__ structura noastră de date, vor //efectua// prelucrările specifice fiecărei clase, având, totodată, //​posibilitatea de încapsulare a unor informaţii de stare// (cum sunt suma şi numărul din exemplul anterior)
poo-ca-cd/laboratoare/visitor.txt · Last modified: 2023/11/19 14:55 by aconstantinescu1704
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