Это может быть немного далеко в левом поле, но, поскольку Java 5 и выше имеют обобщенные элементы, традиционные шаблоны наблюдателя и слушателя кажутся немного устаревшими.То есть типы являются лингва-фракой Java в наши дни.События с целочисленными идентификаторами существуют главным образом потому, что операторы switch для констант чрезвычайно эффективны - за счет читабельности и часто требуют, чтобы приведения делали что-нибудь полезное (вы можете знать, что если ID = 23, то объект должен быть MouseEvent, но это лучшеи безопаснее, если вы позаботитесь об этом для информации о типе компилятора и времени выполнения).На современной машине в современной JVM эффективность может не стоить того.
Итак, если вы не состоите в браке с идентификаторами и традиционным шаблоном наблюдения, вы можете рассмотреть что-то вроде этого:
public abstract class Observer<T> {
private final Class<T> type;
protected Observer(Class<T> type) {
this.type = type;
}
//implement this method; if it returns false, the event (object)
//is "consumed" and no other observers should be called
public abstract boolean onEvent(T instance);
protected final boolean matches(Object obj) {
return type.isInstance(obj);
}
Boolean maybeDispatch(Object o) {
if (matches(o)) {
return onEvent(type.cast(o));
}
return null;
}
}
Это дает нам (в буквальном смысле) общий наблюдатель событий;мы включаем тип передаваемого объекта следующим образом:
public class Bus {
private final List<Observer<?>> observers = new ArrayList<Observer<?>>();
public void registerObserver(Observer<?> observer) {
observers.add(observer);
}
public <T> void onEvent(T t) {
Boolean keepGoing;
for (Observer<?> obs : observers) {
keepGoing = obs.maybeDispatch(t);
if (keepGoing != null && !keepGoing.booleanValue()) {
break;
}
}
}
}
Результирующий код (незначительно) менее эффективен, но запись подкласса такого «наблюдателя» бесконечноболее читабельным.Он не очень похож на традиционный шаблон наблюдателя, но функционально эквивалентен.
Если вам все еще нужен дополнительный параметр «события», вы можете просто выполнить аналогичную логику для параметризации двух типов.