2010-12-03 6 views
7

Si tengo un objeto que quiero poder observar varios otros objetos observables, no todos del mismo tipo. Por ejemplo, quiero que A pueda observar B y C. B y C no están relacionados, excepto por el hecho de que ambos implementan Observable.Observando múltiples observables mientras se evita el operador instanceof en java?

La solución obvia es sólo para usar "si instanceof" dentro del método de actualización, pero que rápidamente puede llegar a ser complicado y, como tal, me pregunto si hay alguna otra manera?

Respuesta

7

similares a las sugerencias anteriores se podía cambiar de actualizar a.

public void update(Observable o, Object arg) { 
    try{ 
    Method update = getClass().getMethod(o.getClass(), Object.class); 
    update.invoke(this, o, arg); 
    } catch(Exception e) { 
    // log exception 
    } 
} 

De esta manera usted puede agregar un método

public void update(A a, Object arg); 
public void update(B b, Object arg); 
public void update(C c, Object arg); 

para cada tipo que desea observar. Desafortunadamente, necesitas saber el tipo concreto exacto del Observable. Sin embargo, podría cambiar las reflexiones para permitir interfaces, etc.

0

Suponiendo que las operaciones en el objeto B/C serían idénticas y simplemente desea distinguir entre los dos objetos para malabarismos de estado, también podría crear un objeto delegado que implemente la lógica/estado de observación real y use una búsqueda mecanismo en su objeto principal para recuperar el delegado correcto para el objeto Observable particular. Luego reenvía las llamadas.

0

Siempre puede tener un Map<Class<? extends Event>, EventHandler> en su oyente. Operador similar, pero no explícito de 'instancia'. Se reemplaza con containsKey() en un mapa.

12

Una solución limpia sería utilizar clases internas (anónimas) en A para actuar como Observer s. Por ejemplo:

class A { 
    public A(B b, C c) { 
     b.addObserver(new BObserver()); 
     c.addObserver(new CObserver()); 
    } 

    private class BObserver implements Observer { 
     // Logic for updates on B in update method 
    } 

    private class CObserver implements Observer { 
     // Logic for updates on C in update method 
    } 
} 

Esto le permitirá añadir BObserver/CObserver casos sin embargo muchos de B s y s C que realmente quiere ver. Tiene la ventaja añadida de que la interfaz pública A 's es menos desordenada y se pueden añadir fácilmente nuevas clases internas para manejar clases D, y EF.

+3

Es casi seguro que desea hacer sus clases internas anónimas. –

+0

Generalmente, sí, pero para este ejemplo las clases nombradas lo hacen un poco más legible. –

Cuestiones relacionadas