|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Feb 2009
Messaggi: 700
|
[Java] Realizzare il pattern Observer
Ciao,
stò studiando i pattern applicati a Java. Attualmente mi stò vedendo il pattern Observer che viene usato praticamente in tutte le GUI. Mi dite se ho capito bene? Allora io ho sostanzialmente ho due tipi di oggetti: 1) Un SOGGETTO (o publisher) che di fatto rappresenta i miei dati. 2) Vari OBSERVER (o listener) che di fatto rappresentano una specifica vista dei mie dati (mantenendosi sincronicatti con il soggetto) La logica che ci stà dietro è la seguente: Il soggetto rappresenta i miei dati e si manterrà una lista di tutti gli osservatori che lo stanno osservando (che vogliono quindi rappresentare i dati e le loro modifiche quando esse avvengono). Quando i dati subiscono una modifica il soggetto invia una notifica a tutti i suoi osservatori che si auto aggiorneranno e forniranno una nuova vista dei dati. (Es: ho un foglio di excell. I dati nel sistema sono il soggetto. La rappresentazione è l'osservatore. Tramite l'osservatore modifico il valore di una cella. Il soggetto ricalcola con una formula i valori di tutte le altre celle del foglio di calcolo che vengono così modificate, così avverte l'osservatore della modifica, esso si aggiorna e visualizza i nuovi valori di tutte le celle) Esempio in codice: Observer la dichiaro come un'interfaccia, poi ovviamente devo implementarla ed in base al tipo concreto dell'Observer il metodo update aggiornerà la vista o farà qualcosa in uno specifico modo: Codice:
/* Interfaccia che rappresenta i vari oggetti osservatori che a loro volta * rappresentano una specifica rappresentazione dei dati */ public interface Observer { public void update(Subject subject) ; // Metodo astratto che modifica i dati } Codice:
import java.util.Vector; /* Classe che rappresenta i dati su cui si basano le viste */ public class Subject{ /* Crea un vettore che conterrà la lista di tutti gli osservatori che lo * osservano */ protected Vector observers = new Vector(); public void addObserver(Observer o){ // Aggiunge un oggetto Observer al vettore observers.addElement(o); } public void removeObserver(Observer o){ // Rimuove un osservatore dal vettore observers.removeElement(o); } /* Notifica agli oggetti osservatori che c'è stata una modifica dei dati * rappresentati da Subject */ public void notify(){ Enumeration e = observers.getElements(); while (e.hasMoreElements()) { /* Invoca il metodo update su tutti gli osservatori per modificare le viste */ ((Observer)e.nextElement()).update(this); } } } Grazie |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Il pattern observer, realizza il relazionamento 1-molti tra il subject ed n ascoltatori, in modo che ogni variazione di stato dell' observable sia ascoltata in broadcast dagli observer. Ovviamente tale logica trova un' applicazione nello slegare i dati applicativi dalla loro rappresentazione. Ad esempio 2 observer potrebbero consumare i dati: uno per mostrarli a video e l' altro per loggarli su file o mandarli in rete.
|
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Feb 2009
Messaggi: 700
|
Ti ringrazio,
mmm...ora però ho un altro problemino con un altro esempio più concreto che non mi gira (purtroppo sono tremendamente arrugginito con Java e diciamo che non ci ho mai fatto nulla di che) L'esempio è questo: INTERFRACCIA Observer: Codice:
/* Rappresenta un generico oggetto osservatore */ public interface Observer { void update(); } Codice:
/* Implementa l'interfaccia Observer e rappresenta uno specifico tipo di oggetto * osservatore */ public class ConcreteObserver implements Observer{ // Specifica quale suggetto stà osservando l'oggetto osservatore private ConcreteSubject subject; /* COSTRUTTORE: crea uno specifico osservatore e gli passa il riferimento * all'oggetto soggetto che si intende osservare */ public ConcreteObserver(ConcreteSubject aSubject){ subject = aSubject; subject.add(this); } /* Metodo pubblico che viene invocato dal soggetto per modificare lo stato * dell'osservatore quando nel soggetto avviene una modifica */ public void update(){ System.out.println("Io sono l'observer " + this + " ed il nuovo stato del mio subject e' " + subject.getState()); } } Codice:
/* Interfaccia che rappresenta un generico soggetto che rappresenta i dati */ public interface Subject { void add(Observer anObserver); // Aggiunge un elemento lista degli osservatori void remove(Observer anObserver); // Rimuove un elemento dalla lista degli osservatori void notify(); // Notifica a tutti gli oggetti osservatori una modifica sui dati } Codice:
import java.util.LinkedList; /* Rappresenta un tipo concreto di Subject ed implementa l'interfaccia Subject */ public class ConcreteSubject implements Subject { private int state; // Rappresenta lo stato del soggetto (il dato rappresentato) private LinkedList observers; // Rappresenta la lista degli osservatori /* Creatore: Crea un oggetto di tipo ConcreteSubject e riceve come input il * dato che si intende rappresentare (lo stato iniziale del soggetto) */ public ConcreteSubject(int initialState){ state = initialState; // Setta lo stato } /* Metodo pubblico che restituisce al chiamante il valore dello stato del * soggetto */ public int getState(){ return state; } /* Metodo pubblico che permette la modifica dello stato del soggetto */ public void setState(int aState) { state = aState; } /* Metodo pubblico che permette di inserire un oggetto osservatore nella lista * di ogetti che osservano il soggetto */ public void add(Observer anObserver) { observers.add(anObserver); } /* Metodo pubblico che permette di rimuovede un oggetto osservatore dalla lista * di ogetti che osservano il soggetto */ public void remove(Observer anObserver) { observers.remove(anObserver); } /* Metodo pubblico che notifica agli oggetti osservatori eventuali modifiche * dei dati nel soggetto */ public void notify(){ Iterator iter=observers.iterator(); // Crea un iteratore su observer Observer obs; // Contiene il riferimento ad un generico Observer while(iter.hasNext()){ // Aggiorna tutti gli observer obs=(Observer)iter.next(); obs.update(); } /* Metodo main() che avvia l'applicazione: prende in input un array di * argomenti */ public static void main(String[] args){ // Crea un array di osservatori di 3 locazioni int concreteObservers[3]; int initialState = 10; // Setta a 10 la variabile initialState // Crea un nuovo soggetto concreto passandogli uno stato iniziale ConcreteSubject mySubject = new ConcreteSubject(initialState); // Stampa lo stato del soggetto appena creato System.out.println("E' stato creato un subject con stato " + mySubject.getState()); /* Crea tre oggetti osservatori e mette il loro riferimento nell'array * concreteObservers */ for (int i = 0; i < 3; i++){ concreteObservers[i] = new ConcreteObserver(mySubject); } System.out.println("..."); mySubject.setState(17); // Cambia il valore dello stato del soggetto mySubject.notify(); // Notifica il cambiamento di stato agli oggetti osservatori System.out.println("..."); mySubject.setState(06); // Cambia il valore dello stato del soggetto mySubject.notify(); // Notifica il cambiamento di stato agli oggetti osservatori } } void notify(); di Subject (forse c'entra con quella cosa che mi dicevi prima?) E poi mi dà una serie di errori dentro la classe ConcreteSubject. Gli errori che mi dà sono: Cannot override the final method from Object ConcreteSubject.java /Observer3/src line 43 Java Problem Iterator cannot be resolved to a type ConcreteSubject.java /Observer3/src line 44 Java Problem Syntax error on token "3", delete this token ConcreteSubject.java /Observer3/src line 56 Java Problem Syntax error, insert "}" to complete Block ConcreteSubject.java /Observer3/src line 48 Java Problem Type mismatch: cannot convert from ConcreteObserver to int ConcreteSubject.java /Observer3/src line 68 Java Problem LinkedList is a raw type. References to generic type LinkedList<E> should be parameterized ConcreteSubject.java /Observer3/src line 10 Java Problem Type safety: The method add(Object) belongs to the raw type LinkedList. References to generic type LinkedList<E> should be parameterized ConcreteSubject.java /Observer3/src line 32 Java Problem Non capisco...l'esempio è prefetto...preso dal sito di un corso universitario...booo |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Sep 2003
Città: Tradate
Messaggi: 396
|
Chiamalo notifica, notify e' un metodo di object che viene ereditato, e tu cosi' tenti di sovrascriverlo..
![]() |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Feb 2009
Messaggi: 700
|
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 00:54.