Documente Academic
Documente Profesional
Documente Cultură
pp2011 Lab12
pp2011 Lab12
Laboratorul 12
12.1. abloane comportamentale
abloanele comportamentale se ocup cu algoritmi i cu atribuirea responsabilitilor ntre obiecte. Pe lng abloanele de obiecte sau de clase, acestea descriu i abloanele de comunicare ntre clase/obiecte. Aceste abloane ajut la concentrarea mai mult asupra modului n care sunt interconectate obiectele i mai puin asupra fluxului complex de control dificil de urmrit la execuie. abloanele comportamentale de clas folosesc motenirea pentru a distribui comportarea ntre clase. Acest grup cuprinde 2 abloane: Template Method i Intepreter. Template Method se refer la o metod ce reprezint o definiie abstract a unui algoritm. Algoritmul este definit pas cu pas, fiecare pas apelnd o operaie abstract sau o operaie primitiv. O subclas ce extinde clasa n cauz completeaz algoritmul, oferind implementri concrete metodelor abstracte. Un Interpreter este o gramatic sub form de ierarhie de clase care implementeaz un interpretor ca o operaie pe instanele acestor clase. abloanele comportamentale de obiect folosesc compunerea obiectelor. Unele dintre aceste abloane descriu felul n care coopereaz un grup de obiecte egale pentru a efectua o operaie ce nu ar fi putut fi efectuat de un singur obiect. Un aspect important este modul n care aceste obiecte egale tiu unele de celelalte. ablonul Observer de exemplu definete o dependen ntre obiecte, un exemplu clasic fiind sistemul MVC (Model View Controller), unde toate vizualizrile unui model sunt ntiinate oricnd modelul i modific starea. Alte abloane ncapsuleaz comportarea ntr-un obiect i deleag cererile ctre acest obiect. 12.1.1. Observer 1) Definiie Se definete o dependen unu la muli ntre obiecte, astfel nct dac un obiect i modific starea, toate obiectele dependente de acesta vor fi notificate. ablonul mai este cunoscut i sub numele de Publish Subscribe sau Dependenti. 2) Aplicabilitate i beneficii Acest ablon permite variaia independent a observatorilor i a obiectelor observate. Se pot reutiliza unele dintre ele, fr a le refolosi pe celelalte. Se pot de asemenea aduga observatori fr a modifica obiectele observate sau ceilali observatori. Cnd se aplic - cnd abstractizarea are dou aspecte, unul depinznd de cellalt. ncapsularea n obiecte separate permite variaia lor n mod independent. - cnd modificarea unui obiect necesit i modificarea altor obiecte, fr a ti care este numrul acestora. - cnd un obiect trebuie s notifice alte obiecte fr s necesite cunoaterea identitii acestora (nu dorim legarea strns ntre acestea) Avantaje
Paradigme de Programare Laboratorul 12 - cuplare abstract ntre subiect i observatori: subiectul are o list de observatori care se conformeaz unei interfee simple, cuplarea fiind redus la minim - comunicare pe scar larg: subiectul nu este interesat de destinatarii unei notifcri, el trimite mesajul tuturor celor abonai la momentul respectiv. Acest lucru permite adugarea i eliminarea de observatori n orice moment necesar. 3) Structura
4) Participani Subject Reine i poate fi observat de mai muli observatori; furnizeaz o interfa pentru ataarea i detaarea acestora Observer Definete interfaa de actualizare ce trebuie implementat de ctre obiectele ce doresc notificri de la Subject ConcreteSubject Reine informaiile ce reprezint interes pentru obiectele observator. Cnd i se modific starea trimite notifcri ctre observatori ConcreteObsever Pastreaz o referin ctre un obiect Subject, reine o stare consecvent cu cea a subiectului i implementeaz Observer pentru a-i putea menine aceast stare n concordan.
12.2. Exemple
1) Exemplu folosire Obsever i Observable API-ul Java ofer dou interfee pentru a uura implementarea acestui ablon: Obsever i Observable. Exemplul urmtor arat cum pot fi folosite aceste interfee.
// MessageBoard.java package test; import java.util.Observable; public class MessageBoard extends Observable { private String message; public String getMessage() { return message; } public void changeMessage(String message) { this.message = message; setChanged(); notifyObservers(message); } public static void main(String[] args) { MessageBoard board = new MessageBoard(); Student bob = new Student(); Student joe = new Student(); board.addObserver(bob); board.addObserver(joe); board.changeMessage("More Homework!"); } } // Student.java package test; import java.util.Observable; import java.util.Observer; class Student implements Observer { public void update(Observable o, Object arg) { System.out.println("Message board changed: " + arg); } }
2) Folosire n GUI ablonul Observer este des folosit n aplicaiile cu interfa utilizator grafic GUI. De exemplu atunci cnd date statistice sufer modificri, mai multe obiecte grafice vor trebui actualizate conform noilor valori: liste, tabele, diagrame .a. Clasa subject n acest exemplu este o fereastr n care se introduce un text, iar clasa observer este o alt fereastr ce afieaz textele introduse n prima fereastr.
// InputForm.java
@SuppressWarnings("serial") class InputForm extends JFrame { public InformDisplay inform = new InformDisplay(); // ... JTextField input = new JTextField(10); public InputForm() { JPanel panel = new JPanel(); input.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { inform.notifyObservers(); } }); panel.add(new JLabel("Enter: ")); panel.add(input); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); getContentPane().add(panel); setTitle("Observable form"); setSize(200, 100); setVisible(true); } public Observable getInputInfo() { return inform; } public String getText() { return input.getText(); } private class InformDisplay extends Observable { public void notifyObservers() { setChanged(); super.notifyObservers(); } } // ... } // DisplayForm.java package test; import javax.swing.*;
12.3. Aplicaie
Aplicaia urmtoare ofer un sistem minimal de organizare a task-urilor din cadrul unei echipe de programare. Diagrama UML este urmtoarea:
Un task n sine este reprezentat de clasa Task, care conine 3 parametri i ofer gettere i settere pentru acetia conform diagramei. Ofer de asemenea o implementare a metodei toString:
public String toString() { return name + " " + notes; }
Operaiile asupra listei de task-uri curente la un moment dat vor genera nite evenimente ce vor fi ascultate de ctre observatori. Implementarea actorului Subject este dat de clasa TaskChangeObservable. Aceasta reine o list editabil de observatori i face dispatch-ul evenimentelor ctre aceti observeri.
private ArrayList<TaskChangeObserver> ArrayList<TaskChangeObserver>(); observers = new
Partea grafic a aplicaiei este format din 3 zone, fiecare necesitnd actualizare atunci cnd lista de task-uri sufer modificri. Pentru o mai uoar implementare se realizeaz o ierarhie de clase ce are la baz clasa TaskPanel:
public abstract class TaskPanel extends JPanel implements ActionListener { public void actionPerformed(ActionEvent e) { } public abstract TaskChangeObserver getObsever(); }
Toate cele 3 clase Panel care vor extinde TaskPanel vor implementa ntr-un fel sau altul interfaa Observer:
interface TaskChangeObserver { public void taskAdded(Task task); public void taskChanged(Task task); public void taskSelected(Task task); }
Cum nu toate dintre ele au nevoie de toate metodele din aceast interfa, vom face i un wrapper ajuttor n acest sens (Adapter pattern):
class TaskChangeObserverAdapter implements TaskChangeObserver { public void taskAdded(Task task) { } public void taskChanged(Task task) { } public void taskSelected(Task task) { } }
Dac nu toate panel-urile vor implementa interfaa TaskChangeObserver i nici nu pot extinde clasa Adapter, atunci toate trebuie s ofere un mod uniform de a oferi un obiect de tip Observer, lucru 7
Paradigme de Programare Laboratorul 12 realizat prin metoda getObserver din TaskPanel. Clasele care nu implementeaz interfaa vor folosi compunerea: o instan privat realizat printr-o clas intern. TaskEditorPanel este zona care ofer posibilitatea de a crea un task sau de a modifica parametrii unui task deja existent. Acest panel rspunde la evenimentul de selectare a unui nou task i genereaz evenimentele de creare i modificare de task.
package test; import import import import import import import java.awt.BorderLayout; java.awt.GridLayout; java.awt.event.ActionEvent; javax.swing.JButton; javax.swing.JLabel; javax.swing.JPanel; javax.swing.JTextField;
@SuppressWarnings("serial") class TaskEditorPanel extends TaskPanel { private TaskChangeObserver taskObserver; private JPanel controlPanel; private JPanel editPanel; private JButton add; private JButton update; private JButton exit; private JTextField taskName; private JTextField taskNotes; private JTextField taskTime; private TaskChangeObservable notifier; private Task editTask; public TaskEditorPanel(TaskChangeObservable newNotifier) { notifier = newNotifier; taskObserver = new TaskChangeObserverAdapter() { public void taskSelected(Task task) { editTask = task; taskName.setText(task.getName()); taskNotes.setText(task.getNotes()); taskTime.setText("" + task.getTimeRequired()); } }; createGui(); } public void createGui() { setLayout(new BorderLayout()); editPanel = new JPanel(); editPanel.setLayout(new GridLayout(3, 2)); taskName = new JTextField(20); taskNotes = new JTextField(20); taskTime = new JTextField(20); editPanel.add(new JLabel("Task Name")); editPanel.add(taskName); editPanel.add(new JLabel("Task Notes")); editPanel.add(taskNotes);
TaskSelectorPane reprezint zona unde se poate alege un task din lista de task-uri deja create. Aceast zon rspunde la evenimentul de creare de nou task, care este introdus n list, i genereaz evenimentul de selecie a unui nou task.
package test; import java.awt.event.ActionEvent; import javax.swing.JComboBox; @SuppressWarnings("serial")
TaskHistoryPanel este zona de mesaje n care se rein toate operaiile efectuate. Se ascult toate evenimentele generate de Subject i nu se genereaz nici unul.
package test; import java.awt.BorderLayout; import javax.swing.JScrollPane; import javax.swing.JTextArea; @SuppressWarnings("serial") class TaskHistoryPanel extends TaskPanel implements TaskChangeObserver { private JTextArea displayRegion; public TaskHistoryPanel() { createGui(); } public void createGui() { setLayout(new BorderLayout()); displayRegion = new JTextArea(10, 40); displayRegion.setEditable(false); add(new JScrollPane(displayRegion)); } public void taskAdded(Task task) { displayRegion.append("Created task " + task + "\n");
10
Partea de interfa grafic, unde se instaniaz aceste panel-uri, ar putea cuprinde urmtoarele:
TaskPanel select = new TaskSelectorPanel(observable); TaskPanel history = new TaskHistoryPanel(); TaskPanel edit = new TaskEditorPanel(observable); observable.addTaskChangeObserver(select.getObsever()); observable.addTaskChangeObserver(history.getObsever()); observable.addTaskChangeObserver(edit.getObsever()); observable.addTask(new Task());
12.4. Teme
12.4.1. Tema 1 Extindei aplicaia de la seciunea 12.2 astfel nct mai multe ferestre observer s asculte mesajele introduse in fereastra subiect. Numrul acestor ferestre trebuie s fie variabil i s poat fi controlat n timpul rulrii. De exemplu un buton n fereastra display permite instanierea unui nou observer, iar inchiderea unei ferestre observer nu mai duce la nchiderea ntregii aplciaii. 12.4.2. Tema 2 Construii clasele i interfeele conform diagramei i explicaiilor de la seciunea 12.3 i realizai fereastra grafic care s cuprind cele 3 panel-uri. Extindei aplicaia astfel nct s se poate terge task-urile selectate.
11