|
|||||||
|
|
|
![]() |
|
|
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: 20:32.




















