Differences

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

Link to this comparison view

poo:breviare:breviar-11 [2025/11/30 16:29]
george.tudor1906 [Breviar 11]
poo:breviare:breviar-11 [2025/12/14 17:41] (current)
george.tudor1906
Line 1: Line 1:
 +====== Breviar 11 ======
  
-====== Breviar 9 ======+=== Introducere în Design Patterns ​===
  
-=== Interfețe grafice (GUI) ===+== 1. Ce reprezintă design patterns? ​==
  
-=== 1Introducere ===+Design patterns reprezintă soluții generale, reutilizabile,​ pentru probleme des întâlnite în cadrul software design. 
 +Un design pattern este o schemă a unei soluții pentru o problemă de design (nu reprezintă un algoritm sau o bucată de cod care poate fi aplicată direct), 
 +ce poate ușura munca programatorului și poate duce la simplificarea și eficientizarea arhitecturii unei aplicații.
  
-== 1.1 Contextul interfețelor grafice ​==+== 2Tipuri de design patterns ​==
  
-În cazul programelor pe care le-am făcut până acumtoate mesajele ​și răspunsurile apăreau ca linii de text sugestive, ecranul fiind folosit în mod text.+Există 3 tipuri de design patternsîn funcție de aspectul ​și de funcționalitatea obiectelor:
  
-Un astfel ​de stil de comunicare nu este atractiv pentru utilizatorimotiv pentru care se preferă dialogul prin **interfețe grafice** sau **GUI** (//Graphical User Interface//​)ecranul fiind folosit în mod grafic.+  * **Behavioral Patterns**: tratează modul de interacționare între obiecte (ObserverStrategy, Visitor, Command); 
 +  ​* **Creational Patterns**: tratează modul de creare a obiectelor (Factory, Singleton, Builder); 
 +  ​* **Structural Patterns**: tratează modul cum este reprezentat un obiect și cum sunt relațiile între entități ​(DecoratorComposite, Proxy, Facade, Adapter).
  
-<note important>​ +=== 1Creational Patterns ===
-În trecerea de la o versiune la alta, bibliotecile de clase care oferă servicii grafice au suferit, probabil, cele mai mari schimbăriAcest lucru se datorează, pe de o parte, dificultății legate de implementarea noțiunii de portabilitate,​ iar pe de altă parte nevoii de a integra mecanismele GUI cu tehnologii apărute și dezvoltate ulterior. +
-</​note>​+
  
-== 1.2 Modalități de creare a interfețelor grafice ​==+== 1.1 Singleton Pattern ​==
  
-În momentul actual, există două modalități de a crea o aplicație cu interfață grafică:+=== Descriere ===
  
-  * **AWT (Abstract Windowing Toolkit)** ​este API-ul inițial pus la dispoziție începând cu primele versiuni ​de Java; +Uneori ne dorim să avem un obiect care să apară doar o singură dată într-o aplicație (de exemplu conducătorul unei țări). 
-  * **Swing** - este parte dintr-un proiect mai amplu numit **JFC (Java Foundation Classes)** creat în urma colaborării dintre Sun, Netscape și IBM, care se bazează pe modelul AWT, extinzând funcționalitatea acestuia și adăugând sau înlocuind unele componente pentru dezvoltarea aplicațiilor GUI.+De aceea folosim ​**Singleton**un mod prin care restricționăm numărul de instanțieri ale unei clase: clasa are o singură instanță, 
 +care va fi folosită în întreg proiectul.
  
-<note tip> +Pentru ​asigura restricționarea:
-Este preferabil ca aplicațiile Java să fie create folosind tehnologia **Swing**, deoarece aceasta pune la dispoziție o paletă mult mai largă de facilități,​ însă nu se va renunțcomplet la AWT, deoarece aici există clase esențiale, reutilizate în Swing. +
-</​note>​+
  
-=== 2Pachetul Swing ===+  * constructorul clasei de tip Singleton este **privat** (astfel blocăm instanțierea multiplă din exterior);​ 
 +  * avem un membru **static** și **privat** care reține instanța unică; 
 +  * avem o metodă **statică** și **publică** prin care returnăm instanța (se creează dacă nu există deja).
  
-== 2.1 Caracteristici ==+Există două abordări frecvente:​ 
 +  * **lazy instantiation** (instanța se creează la prima cerere); 
 +  * **eager instantiation** (instanța se creează imediat, la încărcarea clasei).
  
-Componentele **Swing**, spre deosebire ​de predecesoarele din versiunile Java anterioare, sunt implementate în întregime în Java. Aceasta are ca rezultat o mai bună compatibilitate cu platforme diferite decât în cazul folosirii componentelor AWT.+<code java> 
 +public class SingletonClass { 
 +    /* 
 +    la inceputinainte ​de prima si singura instantiere a clasei SingletonClass 
 +    va avea valoarea null 
 +    */ 
 +    private static SingletonClass obj = null;
  
-Unul din principalele deziderate ale tehnologiei Swing a fost să pună la dispoziție un set de componente GUI extensibile care să permită dezvoltarea rapidă de aplicații Java cu interfață grafică competitivă,​ din punct de vedere comercial.+    public int value = 10;
  
-Cel mai important pachet, care conține componentele de bază este **javax.swing**.+    // lasam constructorul clasei privat pentru a nu fi accesat din exterior 
 +    private SingletonClass() { 
 +        // do stuff 
 +        System.out.println("​Instantiam!"​);​ 
 +    }
  
-== 2.2 Elementele unei interfețe utilizator ==+    // metoda prin care se creaza unica instanta a clasei 
 +    // lazy instantiation 
 +    public static SingletonClass getInstance() { 
 +        // daca clasa nu a fost instantiata inainte, o facem acum 
 +        if (obj == null) 
 +            obj new SingletonClass();​ 
 +        return obj; 
 +    }
  
-Orice interfață utilizator Java este compusă din următoarele elemente:+    public void show() { 
 +        System.out.println("​Singleton is magic"​);​ 
 +    } 
 +
 +</​code>​
  
-  * **Componente** - orice poate fi plasat pe o interfață utilizator, cum ar fi butoane, liste de derulare, meniuri pop-up, casete de validare sau câmpuri de text; +=== Avantaje / Dezavantaje ===
-  * **Containere** - acestea reprezintă componente care pot conține alte componente (de exemplu panouri, casete de dialog sau ferestre independente);​ +
-  * **Administratori de dispunere** - reprezintă obiecte care definesc modul în care sunt aranjate (dispuse) componentele într-un container. Administratorul de dispunere nu este vizibil într-o interfață,​ însă sunt vizibile rezultatele "​muncii"​ sale.+
  
-<note tip> +Un avantaj ​este accesul ușor la instanța globală, fără a avea nevoie să o transmitem ca parametru sau să o instanțiem manual.
-Dispunerea componentelor interfeței ​este de mai multe feluri: +
-  * dispunere secvențială+
-  * dispunere tabelară+
-  * dispunere marginală+
-  * dispunere tabelară neproporțională. +
-</​note>​+
  
-=== 3Crearea ferestrelor ===+<code java> 
 +public void modifyValue (int x) { 
 +    SingletonClass.getInstance().value ​x; 
 +    // se modifica valoarea lui value din clasa 
 +}
  
-== 3.1 Clasa JFrame ==+SingletonClass.getInstance().show();​ 
 +</​code>​
  
-Clasa **JFrame** este cea pe care o vom folosi pentru a crea ferestre. Ca orice altă clasă care reprezintă componente Swing ea se află în pachetul //​javax.swing//​. +<note warning> 
- +Singleton poate fi dezavantajos la testaredeoarece leagă dependențe între ​clase și îngreunează izolarea acestora. 
-Pentru că este un container, vom folosi, de cele mai multe oriaceastă clasă prin moștenire nu prin instanțiere. Altfel spus, vom crea clase care să reprezinte ferestre ​și pentru ca acestea să devină ferestre ​de tip JFrame ele vor moșteni această clasă.+De asemenea, varianta lazy nu este thread-safe în multithreading;​ în astfel ​de situații se preferă eager instantiation (sau alte variante thread-safe). 
 +</​note>​
  
 <code java> <code java>
-public class Fereastra extends JFrame ​+public class SingletonClass ​
-    private ​JButton button; +    private ​static SingletonClass obj = new SingletonClass(); 
- +    ​private SingletonClass() {}
-    public Fereastra(String text) { +
-        super(text);​ +
-        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);​ +
-        setMinimumSize(new Dimension(300,​ 200)); +
-        getContentPane().setBackground(Color.blue);​ +
-        setLayout(new SpringLayout());​ +
-        button ​= new JButton("​Apasa"​); +
-        add(button)+
-        show(); +
-        pack(); +
-    ​}+
  
-    public static ​void main(String args[]) { +    ​// eager instantiation - merge la threaduri 
-        ​Fereastra f = new Fereastra("​Laborator POO");+    ​public static ​SingletonClass getInstance() { 
 +        ​return obj;
     }     }
 } }
 </​code>​ </​code>​
  
-<note important>​ +=== Utilizări ===
-Metoda //​add(Component c)// este folosită pentru a adăuga pe fereastră o componentă exact ca în cazul Applet-urilor. Metoda //add()// este moștenită din clasa **Container**. +
-</​note>​+
  
-=== 4. Crearea butoanelor ===+Utilizări frecvente:
  
-== 4.1 Clasa JButton ==+  * înlocuirea variabilelor globale (instanța Singleton este „globală"​);​ 
 +  * obiecte care reprezintă resurse partajate (de exemplu logger); 
 +  * implementarea de Factory (vezi mai jos).
  
-Un buton poate fi creat folosind clasa **JButton**De obicei, butonul este construit folosind unul dintre constructorii:​+== 1.2 Factory Pattern ==
  
-  * //public JButton();//​ → un buton fără text +=== Descriere ===
-  * //public JButton(String text)// → un buton cu text dat ca parametru +
-  * //public JButton(String text, Icon ico)// → buton cu text și imagine+
  
-Textul ​de pe buton poate fi modificat folosind metoda //​setText(String text)// ​sau poate fi preluat folosind metoda //getText()//.+Uneori suntem nevoiți să creăm obiecte în funcție ​de preferința utilizatorului ​sau de alte necesități. 
 +De aceea folosim **Factory**,​ prin care alcătuim o familie de clase înrudite ​(prin moștenirea aceleiași clase abstracte sau implementarea aceleiași interfețe)
 +iar crearea obiectului concret este delegată către o metodă de tip factory.
  
-<note warning>​ +{{:​poo:​breviare:​factory_pattern_uml_diagram.jpg?500|}}
-Metodele //​setLabel()//​ și //​getLabel()//​ sunt considerate obsolete și nu se mai folosesc în prezent. +
-</​note>​+
  
-== 4.2 Exemplu ​de implementare ​==+==Exemplu ​(pizzas) ​==
 + 
 +În exemplul de mai jos, utilizatorul cere un tip de pizza prin nume; dacă tipul există, primește informații despre pizza.
  
 <code java> <code java>
-class Button extends JFrame implements ActionListener ​+interface IPizza ​
-    ​private JButton button;+    ​void showStuff(); 
 +}
  
-    public Button(String text) { +/* 
-        ​super(text);​ +nu este neaparat sa avem o clasa abstracta ce implementeaza o interfata 
-        ​setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); +putem avea pur si simplu o clasa abstracta ​(fara sa implementeze o interfata
-        ​setMinimumSize(new Dimension(300,​ 200)); +care e extinsa de clasele normale sau o interfata ce e implementata direct de 
-        ​getContentPane().setBackground(Color.blue);​ +clasele normale din Factory 
-        ​setLayout(new SpringLayout());​ +*/ 
-        ​button = new JButton("​Apasa"​);​ +abstract class Pizza implements IPizza { 
-        ​button.addActionListener(this); +    ​public abstract void showStuff(); 
-        ​add(button);​ +} 
-        show(); + 
-        ​pack();+class PizzaMargherita extends Pizza { 
 +    public void showStuff() { 
 +        ​System.out.println("Sos tomat si branza Mozzarella."​);
     }     }
 +}
  
-    ​public ​static ​void main(String args[]) { +class PizzaQuattroStagioni extends Pizza { 
-        ​Button b = new Button("LaboratorPOO");+    ​public void showStuff() { 
 +        ​System.out.println("Sos tomat, branza Mozzarella, sunca, pepperoni, " + 
 +                           "​ciuperci,​ ardei. ​");
     }     }
 +}
  
-    @Override +class PizzaPepperoni extends Pizza { 
-    public void actionPerformed(ActionEvent e) { +    public void showStuff() { 
-        ​/* +        ​System.out.println("​Sos tomat, branza Mozzarella, dublu pepperoni."​);​ 
-        ​JButton button = (JButton)e.getSource(); +    } 
-        if (button.getText().equals("​Apasa")) +
-            ​// valabil dacă aveam mai multe butoane ascultate de acest ascultător + 
-        ​*/ +class PizzaHawaii extends Pizza { 
-        ​System.out.println("Butonul a fost apasat!");+    public void showStuff() 
 +        System.out.println("Sos tomat, branza Mozzarella, sunca, dublu ananas."​); 
 +    } 
 +
 + 
 +class PizzaFactory { 
 +    public static Pizza factory (String pizzaName) { 
 +        if (pizzaName.equals("​Margherita"​)
 +            return new PizzaMargherita();​ 
 +        if (pizzaName.equals("​Hawaii")) 
 +            ​return new PizzaHawaii();​ 
 +        ​if (pizzaName.equals("​Quattro Stagioni"​)) 
 +            return new PizzaQuattroStagioni();​ 
 +        ​if (pizzaName.equals("Pepperoni")
 +            return new PizzaPepperoni();​ 
 +        return null;
     }     }
 } }
 </​code>​ </​code>​
  
-<note important>​ +== 1.3 Builder Pattern ==
-Din moment ce butonul reprezintă o componentă,​ poate fi adăugat pe un container folosind metoda //​add(Component c)// a containerului.+
  
-Butonul **JButton** este sensibil la evenimente de tip **ActionEvent**,​ așadar, modalitatea de atașare a ascultătorilor și de creare evenimente este similară butoanelor Button din pachetul //​java.awt//​. +=== Descriere ===
-</​note>​+
  
-=== 5Crearea componentelor text ===+Acest pattern este folosit în restaurantele de tip fast food care furnizează meniul pentru copii. 
 +Un meniu pentru copii constă de obicei într-un fel principal, unul secundar, o băutură și o jucărie. 
 +Pot exista variații în ceea ce privește conținutul meniului, dar procesul de creare este același. 
 +Fie că la felul principal se alege un hamburger sau un cheeseburger,​ procesul va fi același. 
 +Vânzătorul le va indica celor din spate ce să pună pentru fiecare fel de mâncare, pentru băutură și jucărie. 
 +Toate acestea vor fi puse într-o pungă și servite clienților.
  
-== 5.1 Tipuri de componente text ==+{{:​poo:​breviare:​img.jpg?500|}}
  
-Vom folosi trei tipuri de componente text: **JTextField**,​ **JTextArea** și **JPasswordField**.+Acest șablon realizează ​**separarea construcției de obiecte complexe de reprezentarea lor** astfel încât 
 +același proces să poată crea diferite reprezentări. Builder-ul creează părți ale obiectului complex 
 +de fiecare dată când este apelat și reține toate stările intermediare. Când produsul este terminat, 
 +clientul primește rezultatul de la builder.
  
-  * **JTextField** - este un câmp de text cu un singur rând pe care pot încăpea mai multe caractere. ​În generalaceastă componentă este folosită pentru a introduce ​un text de dimensiuni mici; +În acest modse obține ​un control mai mare asupra procesului ​de construcție de noi obiecte. 
-  * **JTextArea** ​este un câmp de text care permite introducerea unui text pe mai multe rândurideci, această componentă este folosită pentru texte de dimensiuni mai mari; +Spre deosebire de alte pattern-uri din categoria creational, care creau produsele într-un singur pas
-  * **JPasswordField** - este similară componentei JTextField, doar că aceasta ascunde caracterele introduse de utilizator ca în cazul unui câmp pentru introducerea parolei obișnuit.+pattern-ul ​**Builder construiește un produs pas cu pas** la comanda coordonatorului.
  
-<note tip> +=== Exemplu ​(User cu atribute required și optional===
-Metoda folosită pentru preluarea textului dintr-o componentă text este: //getText()// care returnează o instanță de **String**.+
  
-Pentru a modifica textul dintr-un câmp de text, se folosește metoda ​//setText(String ​text)//.+<code java> 
 +public class User { 
 +    private final String firstName; // required 
 +    private final String lastName; ​ // required 
 +    private final int age;          // optional 
 +    private final String phone; ​    // optional 
 +    private final String ​address; ​  // optional
  
-Componenta **JTextArea** are în comportament și metoda //append(String text)// care permite adăugarea unui text la componentă+    private User(UserBuilder builder
-</​note>​+        this.firstName = builder.firstName;​ 
 +        this.lastName = builder.lastName;​ 
 +        this.age = builder.age;​ 
 +        this.phone = builder.phone;​ 
 +        this.address = builder.address; 
 +    }
  
-== 5.2 Exemplu de implementare ==+    public String getFirstName() { 
 +        return firstName;​ 
 +    }
  
-<code java> +    public String getLastName() ​
-class Text extends JFrame implements ActionListener ​+        ​return lastName
-    ​private JButton button+    ​}
-    ​private JTextField user; +
-    private JPasswordField pass;+
  
-    public ​Text(String text) { +    public ​int getAge() { 
-        ​super(text);​ +        ​return age;
-        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);​ +
-        setMinimumSize(new Dimension(300,​ 200)); +
-        getContentPane().setBackground(Color.blue);​ +
-        setLayout(new FlowLayout());​ +
-        button = new JButton("​Apasa"​);​ +
-        button.addActionListener(this);​ +
-        add(button);​ +
-        user = new JTextField(15);​ +
-        add(user);​ +
-        pass = new JPasswordField(15);​ +
-        add(pass);​ +
-        show(); +
-        pack();+
     }     }
  
-    public ​static void main(String args[]) { +    public ​String getPhone() { 
-        ​Text b = new Text("​LaboratorPOO"​);+        ​return phone;
     }     }
  
-    ​@Override +    public ​String getAddress() { 
-    ​public ​void actionPerformed(ActionEvent e) { +        ​return address;
-        ​/* +
-        JButton button = (JButton)e.getSource();​ +
-        if (button.getText().equals("​Apasa"​)) +
-            // valabil dacă aveam mai multe butoane ascultate de acest ascultător +
-        */ +
-        System.out.println(user.getText() + pass.getText());+
     }     }
-} 
-</​code>​ 
  
-=== 6Butoane de selecție ===+    public String toString() { 
 +        return "​User:"​ + this.firstName + " " + this.lastName + " " + 
 +               ​this.age + " " + this.phone + " " + this.address;​ 
 +    }
  
-== 6.1 JCheckBox și JRadioButton ==+    public static class UserBuilder { 
 +        private final String firstName;​ 
 +        private final String lastName; 
 +        private int age; 
 +        private String phone; 
 +        private String address;
  
-Clasele **JCheckBox** și **JRadioButton** definesc componente de tip butoane de selecție.+        public UserBuilder(String firstName, String lastName) { 
 +            this.firstName = firstName;​ 
 +            this.lastName = lastName; 
 +        }
  
-Standard, butoanele **JCheckBox** sunt folosite pentru a crea liste de opțiuni de tip //​multiple-choice// ​(din care poți selecta mai multe variante), iar **JRadioButton** pentru crearea de liste de tip //​single-choice//​ (din care se poate selecta o singură opțiune).+        public UserBuilder age(int age
 +            this.age = age; 
 +            return this; 
 +        }
  
-<note important>​ +        public UserBuilder phone(String phone) { 
-Astfel, pentru butoanele **JRadioButton** adăugăm o nouă clasă **ButtonGroup** cu ajutorul căreia precizăm care sunt butoanele din care se selectează o singură opțiune.+            this.phone = phone; 
 +            return this; 
 +        }
  
-**ButtonGroup** definește un grup de butoane. Din butoanele ce aparțin aceluiași grup, nu putem selecta decât o singură opțiune+        public UserBuilder address(String address) { 
-</​note>​+            this.address = address; 
 +            return this; 
 +        }
  
-== 6.2 Utilizare ==+        public User build() { 
 +            return new User(this);​ 
 +        } 
 +    }
  
-Ambele tipuri de componente se creează similar butoanelor **JButton**În generalacestea nu sunt folosite cu evenimente și prin verificări ale stărilor acestora ​(se verifică dacă este sau nu selectat la un anumit eveniment).+    public static void main(String[] args) { 
 +        User user1 = new User.UserBuilder("​Lokesh"​"​Gupta"​) 
 +                .age(30) 
 +                ​.phone("​1234567"​) 
 +                .address("​Fake address 1234"​) 
 +                .build();
  
-Verificarea stării unei astfel de componente se face folosind metoda //​isSelected()// care returnează //true// dacă butonul este bifat și //false// dacă nu este bifat.+        User user2 = new User.UserBuilder("​Jack",​ "​Reacher"​) 
 +                .age(40) 
 +                .phone("​5655"​) 
 +                ​//no address 
 +                ​.build(); 
 +    } 
 +
 +</​code>​
  
-<note tip> +== 1.4 Singleton Factory ==
-Pentru o înțelegere mai bună, se recomandă analizarea exemplelor propuse în arhiva laboratorului. +
-</​note>​+
  
-=== 7JScrollPane ===+O clasă de tip Factory poate fi utilizată în mai multe locuri în cadrul unui proiect. Pentru a economisi resurse, 
 +putem folosi pattern-ul **Singleton** pentru Factory, astfel încât să existe o singură instanță a clasei Factory.
  
-== 7.1 Descriere == 
  
-**JScrollPane** este o componentă folosită pentru adăugarea de bare de defilare pentru o altă componentă care ar putea depăși dimensiunile containerului în care este adăugată.+=== 2Behavioral Patterns ===
  
-Instanța JScrollPane nu este folosită în acțiunile directe pe care le are componenta pe care o susține. La construirea instanței, i se dă o componentă pentru care este creată și pe care adaugă bare de defilare (//​scrollbars//​).+== 2.1 Observer Pattern ==
  
-Apoi, instanța **JScrollPane** este adăugată pe container în locul componentei din instanța JScrollPane.+=== Descriere ===
  
-== 7.2 Exemplu ​de implementare ==+Acest design pattern stabilește o relație **one-to-many** între obiecte. 
 +Avem un obiect numit **subiect**,​ căruia îi este asociată o colecție (listă) ​de **observatori**. 
 +Observatorii sunt obiecte dependente de subiect și sunt notificate automat de către subiect atunci când în subiect are loc o acțiune 
 +sau o modificare a stării.
  
-<code java> +{{:​poo:​breviare:​observer_breviar.png?​500|}}
-class Text extends JFrame ​{ +
-    private JTextArea textArea; +
-    private JScrollPane scroll;+
  
-    public Text(String text) { +== 2.2 Strategy Pattern ==
-        super(text);​ +
-        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);​ +
-        setMinimumSize(new Dimension(300,​ 200)); +
-        getContentPane().setBackground(Color.blue);​ +
-        setLayout(new FlowLayout());​ +
-        textArea ​new JTextArea(200,​ 100); +
-        textArea.setLineWrap(true);​ +
-        textArea.setWrapStyleWord(true);​ +
-        textArea.setFont(new Font("​Tahoma", ​2, 12)); +
-        scroll ​new JScrollPane(textArea);​ +
-        add(scroll);​ +
-        show(); +
-        pack(); +
-    }+
  
-    public static void main(String args[]) { +=== Descriere ===
-        Text b new Text("​LaboratorPOO"​);​ +
-    } +
-+
-</​code>​+
  
-=== 8Etichete ===+**Strategy** este un design pattern behavioral ce oferă o familie de algoritmi (strategii),​ 
 +încapsulate în clase care oferă o interfață comună de folosire. 
 +Clientul (utilizatorul) poate alege dinamic strategia care va fi folosită.
  
-== 8.1 JLabel ==+{{:​poo:​breviare:​strategy_breviar.png?500|}}
  
-O etichetă reprezintă cea mai simplă componentă. Aceasta ​este folosită pentru afișarea unui text static în cele mai multe cazuri.+Exemplu de motivare: la căutarea unui element într-o colecție, putem alege algoritmul în funcție de proprietăți ale colecției 
 +(de exemplu, dacă este sortată: căutare binară; altfel: iterare liniară).
  
-Textul de pe o etichetă poate fi modificat sau preluat folosind metodele //​getText()//​ și //​setText(String text)//.+== 2.3 Visitor Pattern ==
  
-<note tip> +=== Descriere ===
-Un **JLabel** poate fi uzitat și pentru afișarea unei imagini. În acest caz, nu i se aplică niciun text, ci doar un **ImageIcon**,​ această modalitate fiind considerată cea mai simplă de a afișa o imagine într-un container. +
-</​note>​+
  
-=== 9Tratarea evenimentelor ===+Acest design pattern oferă posibilitatea de a separa un algoritm de structura de date pe care acesta operează,​ 
 +astfel încât să putem adăuga ușor funcții noi care operează peste o familie de clase fără să modificăm structura acestora.
  
-== 9.1 Ce sunt evenimentele?​ ==+Pe scurt, folosim **Visitor** dacă avem tipuri diferite și dorim să adăugăm/​schimbăm operații fără să modificăm clasele.
  
-Un **eveniment** este produs de o acțiune a utilizatorului asupra unei componente grafice și reprezintă mecanismul prin care utilizatorul comunică efectiv cu programul.+{{:​poo:​breviare:​visitor.jpg?500|}}
  
-Exemple de evenimente sunt: +În cadrul pattern-ului:
-  * apăsarea unui buton; +
-  * modificarea textului într-un control de editare; +
-  * închiderea sau redimensionarea unei ferestre.+
  
-<note important>​ +  * avem o interfață **Visitor**, ​care reprezintă operația aplicată;​ 
-Componentele ​care generează anumite evenimente se mai numesc și **surse de evenimente**. +  ​avem o interfață/​clasă abstractă ​**Visitable** (numită în unele scheme **Element**),​ care reprezintă obiectele peste care se aplică operațiile;​ 
-</​note>​+  * Visitor are metode de forma `visit(...)`; 
 +  * Visitable are metoda `accept(Visitor v)`.
  
-== 9.2 Listeners ​(Ascultători de evenimente) ==+=== Exemplu ​(Ls/Cat peste Repository: Director/​Fisier===
  
-Interceptarea evenimentelor generate de componentele unui program se realizează prin intermediul unor clase de tip **listener** ​(ascultător,​ consumator de evenimente).+<code java> 
 +interface Visitor { 
 +    void visit (Director f)
 +    void visit (Fisier f); 
 +}
  
-În Java, orice obiect poate "consuma" ​evenimentecu condiția ​ca acesta să implementeze interfața listener corespunzătoare tipului ​de eveniment pe care dorește să-l intercepteze.+class Ls implements Visitor { 
 +    public void visit (Director f) { 
 +        System.out.println(f.getName());​ 
 +        for (Repository repo: f.getChildren()) { 
 +            System.out.println("\t" ​+ repo.getName());​ 
 +            // afisam numele unui repo (fisier / folder) 
 +        } 
 +    } 
 + 
 +    public void visit (Fisier f) { 
 +        System.out.println("​Not a folder"​);​ 
 +        /* comanda Ls (in acest exemplu) este specifica doar folderelor, 
 +        in acest caz este evidentiat un dezavantaj al Visitor-ului,​ 
 +        faptul ​ca noi trebuie sa implementam metode ​de care nu avem nevoie 
 +        in acest caz se incalca Interface Segregation Principle */ 
 +    } 
 +
 + 
 +class Cat implements Visitor { 
 +    public void visit (Director f) { 
 +        // avertisment ca avem folder, nu fisier 
 +    } 
 +    public void visit (Fisier f) { 
 +        // citire fisier, folosind numele fisierului 
 +    } 
 +
 + 
 +abstract class Repository { 
 +    private String name; 
 +    // numele unui fisier sau folder (de fapt, calea acestuia) 
 +    public String getName() { 
 +        return name; 
 +    } 
 +    public abstract void accept (Visitor f); 
 +
 + 
 +class Fisier extends Repository { 
 +    public void accept (Visitor f) { 
 +        f.visit(this);​ 
 +        // Visitor-ul "​viziteaza"​ fisierul, adica acesta 
 +        // efectueaza o operatie asupra fisierului 
 +    } 
 +
 + 
 +class Director extends Repository { 
 +    private List<​Repository>​ children = new ArrayList<>​();​ 
 +    public List<​Repository>​ getChildren() { 
 +        return children; 
 +    } 
 +    public void accept (Visitor f) { 
 +        f.visit(this);​ 
 +    } 
 +
 +</​code>​
  
poo/breviare/breviar-11.1764512945.txt.gz · Last modified: 2025/11/30 16:29 by george.tudor1906
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