Наблюдая за множеством наблюдаемых, избегая оператора instanceof в Java? - PullRequest
7 голосов
/ 04 декабря 2010

Если у меня есть объект, который я хочу иметь возможность наблюдать несколько других наблюдаемых объектов, не все одного типа. Например, я хочу, чтобы A мог наблюдать B и C. B и C совершенно не связаны, за исключением того факта, что они оба реализуют Observable.

Очевидное решение - просто использовать if ifof внутри метода обновления, но это быстро может стать грязным, и поэтому мне интересно, есть ли другой способ?

Ответы [ 4 ]

14 голосов
/ 04 декабря 2010

Чистым решением было бы использование (анонимных) внутренних классов в A, чтобы действовать как Observer s. Например:

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

Это позволит вам добавить BObserver / CObserver экземпляров к тем B s и C s, которые вы действительно хотите посмотреть. Дополнительным преимуществом является то, что открытый интерфейс A менее загроможден, и вы можете легко добавлять новые внутренние классы для обработки классов D, E и F.

7 голосов
/ 04 декабря 2010

Аналогично предыдущим предложениям вы можете изменить свое обновление на.

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

Таким образом, вы можете добавить один метод

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

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

0 голосов
/ 04 декабря 2010

Вы всегда можете иметь Map<Class<? extends Event>, EventHandler> в своем слушателе. Аналогичный, но без явного оператора instanceof. Он заменяется на containsKey() на карте.

0 голосов
/ 04 декабря 2010

Предполагая, что операции над объектом B / C будут идентичны, и вы просто хотите различать два объекта для целей жонглирования состоянием, вы также можете создать объект делегата, который реализует реальную логику / состояние наблюдения и использует механизм поиска в вашем главном объекте, чтобы получить правильный делегат для конкретного наблюдаемого объекта. Затем переадресация звонков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...