При регистрации для событий Java разрешены ли повторяющиеся слушатели? - PullRequest
4 голосов
/ 24 августа 2009

Должен ли метод addListener проверять дубликаты регистраций при вызове? Если так, что должно произойти, если найден дубликат?

final public class exampleCanFire {
    public void addFooListener(FooListener listener) {
      // Before adding listener to private list of listeners, should I check for duplicates?
    }
}

Ответы [ 4 ]

4 голосов
/ 24 августа 2009

Я предпочитаю хранить их в List, а не проверять дубликаты. Некоторые преимущества этого подхода:

  • Слушатели уведомляются в детерминированном порядке и потенциально могут помечать события как «использованные», что приводит к тому, что они не распространяются на последующих слушателей.
  • Можно использовать реализацию CopyOnWriteArrayList, которая позволяет слушателю удалить себя во время обратного вызова уведомления без выброса ConcurrentModificationException (это очень важно и является классической ошибкой при написании событийно-ориентированных код).
3 голосов
/ 24 августа 2009

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

Если вы хотите что-то сделать, я бы просто предложил вывести IllegalArgumentException с сообщением, что вы не можете зарегистрировать одного и того же слушателя дважды.

0 голосов
/ 17 октября 2014

Если обнаружено, что использование списков намного медленнее, чем использование методов, рекомендованных JAVA. Я предполагаю, что методы JAVA имеют более прямое взаимодействие с памятью, или что-то вроде того Несмотря на это, я согласен с j_random_hacker в том, что вы должны знать, что и когда вызывается, и впоследствии рисковать, когда дубликаты слушателей портят друг друга в результате действий, но именно поэтому мы тестируем наши программы, не так ли; -)

0 голосов
/ 24 августа 2009

Храните их в наборе и распространяйте независимо от ответа набора:

Set<FooListener> listeners = new HashSet<FooListener>();

public boolean addFooListener(FooListener listener) {
  return listeners.add(listener);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...