Переименование реализованных методов узора наблюдателя в Java

StackOverflow https://stackoverflow.com/questions/4263258

Вопрос

Я использую наблюдаемый интерфейс класса / наблюдателя в Java для реализации шаблона наблюдателя. Интерфейс наблюдателя требует перезаписи метода обновления (наблюдаемый O, Object Arg).

Проблема в том, что я наблюдаю за справедливым числом классов, и мой метод обновления () очень большой:

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) {
            ...
        }
    }

}

Чтобы разделить метод, я думаю о расширении интерфейса наблюдателя с, например, интерфейсом Aobserver, интерфейс BOBSERVER. Который требует перезаписи Onupdate, Onbupdate .. соответственно. Этот метод также облегчает определение того, что наблюдается, что класс наблюдается на основе интерфейсов, которые он реализует.

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
        ...
    }
}

Проблема в том, что если я наследую наблюдателя, я все еще должен реализовать метод обновления (). Я не могу переименовать его в Onaupdate или какое-то другое имя моего выбора.

Любой совет? Спасибо.

Это было полезно?

Решение

Здесь я закодировал необработанную реализацию с помощью наблюдателя и шаблона посетителей. Вы можете взять это как идею, чтобы улучшить его и заполнить там, где вы видите некоторые отверстия.

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();
    }

}

Я надеюсь, что вы не потеряны. :)

Другие советы

Я предложу создать интерфейс UpdateHandler, чтобы выполнить обработку для любого данного блока кода. Каждый случай можно обрабатывать с картой.

Примеры кода следует:

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

Добавьте поле экземпляра в основной класс следующим образом:

частная карта u003CClassu003C?> , UpdateHandler> Handlers = Новый Hashmap u003CClassu003C?> , Обновить обработчик> ();

Создать метод, чтобы обработчики инициализированы

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

Метод обновлений просто найдет соответствующий обработчик и отправляет вызов

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) ;
    }
}

Эта реализация позволит вам добавить новый обработчик по мере необходимости с минимальными изменениями.

Еще одна возможная реализация может быть сделана базой на предыдущей работе, всего на 3 шаговой процедуре.

1) Изменить декларацию поля обработчиков.

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

2) Изменить метод инициализации

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

3) Измените основной способ обновления, чтобы создать новый экземпляр прилагаемой реализации UpdateHandler.

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

Переместите куски кода в каждом состоянии, чтобы соответствующим образом названные методы.

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
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top