2013-03-15 9 views
30

Supponiamo di avere una variabile definita usando la dichiarazione int someVariable;. Mentre il codice viene eseguito, il valore della variabile cambia.Come creare un listener di modifiche per la variabile?

Come posso tracciare i cambiamenti in questa variabile? Come posso implementare un listener che si comporta come onSomeVariableChangedListener?

Ho anche bisogno di sapere quando è stato eseguito un altro metodo in una pagina in modo da poter impostare un listener in un'altra classe.

+0

Sei interessato a fare questo con lo scopo di debug o si desidera utilizzare questo nel codice di produzione? –

+0

nel codice di produzione – Sinigami

risposta

26

Questo è uno dei tanti motivi per nascondere le variabili dietro setter/getter coppie. Quindi nel setter puoi comunicare al tuo ascoltatore che questa variabile è stata modificata nel modo appropriato. Come hanno commentato gli altri, non esiste un modo per fare esattamente quello che vuoi, devi implementarlo tu stesso.

In alternativa, Benjamin mostra uno schema interessante, chiamato pattern Decorator, che potrebbe essere utile se il codice in questione non può essere modificato. You can look up more info at wikipedia

L'idea è di creare un wrapper compatibile attorno a un oggetto. Diciamo che il tuo oggetto in questione è di tipo MyClass.

class MyClass{ 
    publc void doFunc(){...} 
} 

class MyLoggedClass extends MyClass{ 
    MyClass myObject; 

    publc void doFunc(){ 
     //Log doFunc Call 

     myObject.doFunc(); 

    } 
} 

invece di

MyClass object = new MyClass(); 

Si potrebbe utilizzare

MyClass object = new MyLoggedClass(new MyClass()); 

Ora il vostro resto del codice sarebbe utilizzare l'oggetto come al solito, solo che ogni chiamata di funzione sarà registrata, o notificato , ecc.

Come vedrete in wikipedia, questo è tipicamente fatto tramite un'interfaccia che la classe in questione eredita da, ma questo potrebbe non essere possibile nel tuo caso.

+1

Si potrebbe voler menzionare il concetto di Decoratori, che potrebbe essere un modo per attuare una soluzione a questo problema, preferibilmente con un esempio di base. –

+0

nella tua ultima riga, intendevi 'MyClass object = new MyLoggedObject ...' invece di '... myLoggedClass ...'? Se sì, potresti aggiornare per favore? E se è corretto com'è, puoi spiegare per favore? Grazie. – dbconfession

+0

@dbconfession good eye, ho intenzione di aggiustarlo in un altro modo, rinominando la classe –

1

Non esiste un modo integrato in Java per ricevere una notifica se il valore di una variabile arbitraria cambia o se è stato chiamato un metodo.

3

How to Write a Property Change Listener potrebbe aiutare E 'qualcosa riferiscono

+0

Per quanto posso dire, vuole ascoltare le modifiche su una variabile e _non_ una proprietà –

+0

@BenjaminGruenbaum, secondo la mia conoscenza le 'variabili' di un bean o classe sono chiamate come' proprietà', non è su un file '.property'. – Patriks

33

Java offre una semplice implementazione del pattern Observer per questo genere di cose, ma è necessario impostare la variabile osservata in un metodo che gestisca le notifiche dei listener. Se non puoi estendere Observable, puoi usare la composizione (cioè avere un'istanza Observable nella tua classe per gestire le notifiche), oppure puoi dare un'occhiata a java.util.Observable per avere un'idea di come eseguire il rollover versione.

Flux.java

import java.util.Observable; 

public class Flux extends Observable { 
    private int someVariable = 0; 

    public void setSomeVariable(int someVariable) { 
    synchronized (this) { 
     this.someVariable = someVariable; 
    } 
    setChanged(); 
    notifyObservers(); 
    } 

    public synchronized int getSomeVariable() { 
    return someVariable; 
    } 
} 

Heraclitus.java

import java.util.Observable; 
import java.util.Observer; 

public class Heraclitus implements Observer { 
    public void observe(Observable o) { 
    o.addObserver(this); 
    } 

    @Override 
    public void update(Observable o, Object arg) { 
    int someVariable = ((Flux) o).getSomeVariable(); 
    System.out.println("All is flux! Some variable is now " + someVariable); 
    } 
} 
+0

Questo fallisce con la riflessione, ho un requisito simile di listener di modifiche. Ma i valori variabili vengono impostati da dozer, che funziona tramite riflessione. – Vikash

Problemi correlati