Pregunta

Estoy usando la interfaz de la clase Observable / Observador en Java para implementar el patrón de observador. La interfaz Observador requiere sobrescribir el método de actualización (observable o, arg Object).

El problema es que estoy observando un buen número de clases, y mi método update () se ha hecho muy grande:

public class Foo implements Observer {
    ....

    public void update(Observable o, Object param) {
        if (o instanceof A) {
            // large chunk of code
            ...
        } else if (o instanceof B) {
            // large chunk of code
            ...
        }
            ...
        } else if (o instanceof H) {
            ...
        }
    }

}

Con el fin de dividir el método, estoy pensando de extender la interfaz de observador con, por ejemplo AObserver interfaz, interfaz de BObserver .. que requiere sobreescritura onAUpdate, onBUpdate .. respectivamente. Este método también hará que sea más fácil de determinar qué observables la clase está observando basa en las interfaces que está en la ejecución.

class Foo implements AObserver, BObserver {
    ....

    public void onAUpdate(Observable o, Object param) {
        if (o instanceof A) {
        // large chunk of code
        ...
    }

    public void onBUpdate(Observable o, Object param) {
        if (o instanceof B) {
        // large chunk of code
        ...
    }
}

El problema es que si heredo Observador, todavía tengo que poner en práctica el método de actualización (). No puedo cambiar el nombre a onAUpdate o algún otro nombre de mi elección.

Cualquier consejo? Gracias.

¿Fue útil?

Solución

Aquí codificado utilizando una implementación prima observador y el patrón de visitante. Usted puede tomar esto como una idea para mejorar sobre ella y para llenar siempre que vea algunos agujeros.

public interface IObserver extends Observer {
    public void add(AbstractObservable observable, IObserverVisitor visitor);
    public void remove(AbstractObservable observable);
    public void removeAll();
}

public class Observer implements IObserver {

    Map<AbstractObservable, IObserverVisitor> observableMap =
            new HashMap<AbstractObservable, IObserverVisitor>();

    public void add(AbstractObservable observable, IObserverVisitor visitor) {
        observableMap.put(observable, visitor);
    }

    public void remove(AbstractObservable observable) {
        observableMap.remove(observable);
    }

    public void removeAll() {
        observableMap.clear();
    }

    public void update(Observable o, Object arg) {
        observableMap.get(o).visit(this, o, arg);
    }

}

public class AbstractObservable extends Observable{

    public synchronized void addObserver(IObserver o, IObserverVisitor visitor) {
        o.add(this, visitor);
        super.addObserver(o);
    }

    public synchronized void deleteObservers(IObserver o) {
        o.removeAll();
        super.deleteObservers();
    }

    public synchronized void deleteObserver(IObserver o) {
        o.remove(this);
        super.deleteObserver(o);
    }

    @Override
    public synchronized void deleteObserver(Observer o) {
        throw new UnsupportedOperationException();
    }

    @Override
    public synchronized void addObserver(Observer o) {
        throw new UnsupportedOperationException();
    }

    @Override
    public synchronized void deleteObservers() {
        throw new UnsupportedOperationException();
    }

    @Override
    public synchronized int countObservers() {
        return super.countObservers();
    }

    @Override
    public synchronized boolean hasChanged() {
        return super.hasChanged();
    }

    @Override
    public void notifyObservers() {
        super.notifyObservers();
    }

    @Override
    public void notifyObservers(Object arg) {
        super.notifyObservers(arg);
    }

    @Override
    protected synchronized void clearChanged() {
        super.clearChanged();
    }

    @Override
    protected synchronized void setChanged() {
        super.setChanged();
    }

}

public class Observable1 extends AbstractObservable {
    public void changeSomething() {
      setChanged();
      notifyObservers();
    }
}

public class Observable2 extends AbstractObservable {
    public void changeSomething() {
      setChanged();
      notifyObservers();
    }
}

public interface IObserverVisitor {
    void visit(IObserver obsrvr, Observable obsrvable, Object o);
}

public class ObserverVisitor1 implements IObserverVisitor{

    public void visit(IObserver obsrvr, Observable obsrvable, Object o) {
        System.out.println("updated one");
    }

}

public class ObserverVisitor2 implements IObserverVisitor{

    public void visit(IObserver obsrvr, Observable obsrvable, Object o) {
        System.out.println("updated two");
    }
}

public class ObserverTest {

    @Test
    public void testAnything() {
        Observable1 obsrvable1 = new Observable1();
        Observable2 obsrvable2 = new Observable2();

        Observer obsrvr = new Observer();
        obsrvable1.addObserver(obsrvr, new ObserverVisitor1());
        obsrvable2.addObserver(obsrvr, new ObserverVisitor2());

        obsrvable1.changeSomething();
        obsrvable2.changeSomething();
    }

}

espero que no se pierdan. :)

Otros consejos

voy a sugerir a crear una interfaz UpdateHandler para hacer el procesamiento de cualquier bloque de código dado. Cada caso puede ser la manija con un mapa.

Código de ejemplo siguiente:

// Interface to implement for each case
public interface UpdateHandler {
    public void update(Observable source, Object data) ;
}

Añadir un campo de instancia a la clase principal de la siguiente manera:

private Map<Class<?>, UpdateHandler> handlers = new HashMap<Class<?>, Update Handler>();

Crear un método para que los manipuladores inicializado

protected void initializeHandler() {
    handler.put(Integer.class, new IntegerUpdateHandler());
    handler.put(String.class, new StringUpdateHandler());
    ...
}

El método actualizaciones simplemente encontrará el manejador apropiado y enviar la llamada

public void update(Observable source, Object data)
{
    UpdateHandler handler = handlers.get(data.getClass()) ;
    if (handler == null) 
    {
        // use a default handler ? throw an exception ? your choice ;)
    } else {
        handler.update(source, data) ;
    }
}

Esta aplicación le permitirá añadir nuevo controlador según sea necesario con cambios mínimos.

Otra posible aplicación puede ser realizado sobre la base del trabajo anterior, sólo un procedimiento de 3 pasos.

1) Cambiar la declaración del campo de los manipuladores.

Map<Class<?>, Class<? extends UpdateHandler>> handlers ;

2) cambiar el método initialize

handlers.put(Integer.class, IntegerInputHandler.class);

3) cambiar el método de actualización principal para crear una nueva instancia de la aplicación UpdateHandler proporcionada.

UpdateHandler handlerInstance = null ;
Class<? extends UpdateHandler> handler = null ;
handler = handlers.get(data.getClass()) ;
...
handlerInstance = handler.newInstance() ;
handlerInstance.update(source, data) ;

Mover los trozos de código dentro de cada condición a los métodos apropiadamente con nombre.

public void update(Observable o, Object param) {
    if (o instanceof A) {
         onAUpdate(o, param);
    }

    if (o instanceof B) {
         onBUpdate(o, param);
    }
}

public void onAUpdate(Observable o, Object param) {

    // large chunk of code
}

public void onABUpdate(Observable o, Object param) {

    // large chunk of code
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top