2009-11-01 28 views

Respuesta

41

Me gustaría recomendar evitar el uso de la clase Observable por completo, sino más bien definen los detectores específicos del evento y definiciones de eventos correspondientes. Luego, defina una lista de oyentes dentro de su clase junto con métodos para agregar y eliminar oyentes, y propagar eventos a ellos (ver a continuación).

Observable obligue a utilizarlo java.lang.Object para representar eventos y luego comprobar el tipo de evento utilizando instanceof, que es un enfoque fea no OO, y hace que el código sea más difícil de entender. Si observa las clases dentro del paquete javax.swing, verá que evitaron usar Observer/Observable en conjunto y utilizaron un enfoque similar al siguiente.

definición de evento

public class MyChangeEvent extends EventObject { 
    // This event definition is stateless but you could always 
    // add other information here. 
    public MyChangeEvent(Object source) { 
    super(source); 
    } 
} 

Listener Definición

public interface MyChangeListener { 
    public void changeEventReceived(MyChangeEvent evt); 
} 

Clase Definición

public class MyClass { 
    // Use CopyOnWriteArrayList to avoid ConcurrentModificationExceptions if a 
    // listener attempts to remove itself during event notification. 
    private final CopyOnWriteArrayList<MyChangeListener> listeners; 

    public class MyClass() { 
    this.listeners = new CopyOnWriteArrayList<MyChangeListener>(); 
    } 

    public void addMyChangeListener(MyChangeListener l) { 
    this.listeners.add(l); 
    } 

    public void removeMyChangeListener(MyChangeListener l) { 
    this.listeners.remove(l); 
    } 

    // Event firing method. Called internally by other class methods. 
    protected void fireChangeEvent() { 
    MyChangeEvent evt = new MyChangeEvent(this); 

    for (MyChangeListener l : listeners) { 
     l.changeEventReceived(evt); 
    } 
    } 
} 
+1

java.util.Observable también tiene una bandera para indicar si algo ha cambiado. Y a veces una nueva clase de Evento es exagerada. – finnw

+2

+1 para usar CopyOnWriteArrayList – finnw

+0

@finnw: la mayoría de mis definiciones de clases de eventos son <10 líneas de código autogenerado y tardan unos segundos en escribir. Sin embargo, en situaciones donde deseo evitar la definición de nuevas clases de eventos, prefiero PropertyChangeEvent/PropertyChangeListener/PropertyChangeSupport donde al menos se puede inspeccionar el nombre de la propiedad antes de intentar cualquier conversión. – Adamski

0

La herencia múltiple (para extender dos clases) no es posible en Java. Se considera un mal diseño en casi todos los casos.

Si nos brinda más información, quizás alguien pueda ayudarlo un poco más.

1

Java no permite la herencia múltiple, por lo que no hay una forma directa de hacerlo. Usted debe considerar el uso de un patrón de delegado que su principal objeto de que los delegados su comportamiento de observación a un otro objeto ..

class YourObject extends ItsAncestorClass 
{ 
     private Observer includedObserver; 

     public Observer getHisObserver(..) 
} 

Otro enfoque sería convertir el objeto del que su clase está extendiendo a una interfaz, entonces usted se le permitirá extender desde Observer.

+0

@finnw - y Jack nunca dijo nada acerca de que Observer no fuera una clase abstracta. – weiji

-6

Utilice un puente.

Crea una clase que extiende Observable que la primera clase simplemente llama a los métodos de la segunda clase. Método

Puente detalle:

public class XXX { 
    public class XXXObservableBridge : Observable { 
     public void RaiseEvent(); 
     // Listeners etc 
    } 

    private XXXObservableBridge ObservableBridge; 

    XXX() { 
     ObservableBridge = new ObservableBridge; 
    } 

    public Observable AsObservable() { return ObservableBidge; } 

    public void RaiseEvent() { ObservableBridge.RaiseEvent(); } 
} 
+3

-1 esta es una pregunta de Java, no C#. Siga las sintaxis y API de Java – finnw

+0

@finnw C# no necesita el patrón observable/observador y mi código ni siquiera llama a ninguna función API. – Joshua

+1

No hay un IObservable en Java, e incluso si definió uno, java.util.Observable no lo implementa. –

1

Otro La opción es envolver su objeto en un objeto Observable.

public class MyObjectObservableWrapper implements Observable { 
    private MyObject myObject; 
    public MyObjectObservaleWrapper(MyObject myObject){ 
    this.myObject = myObject; 
    } 
    // interface methods here 
} 

Esta opción funciona cuando los datos sean utilizados por los métodos observable es accesible a través de métodos públicos de MiObjeto. Por lo tanto, puede no ser adecuado para todos los casos.

0

Puede extender Observable y ajustar el elemento primario original en su clase infantil observable.Delegue todas las llamadas de método al objeto envuelto.

Cuestiones relacionadas