Шаблон проектирования прослушивателя Java для подписки - PullRequest
4 голосов
/ 21 января 2011

Я пытаюсь спроектировать систему Java, которая похожа на концепцию делегатов c #.

Вот основные функции, которых я хочу достичь:

public class mainform
{
   public delegate onProcessCompleted
//......
    processInformation()
    {
            onProcessCompleted(this);
    }

//......
}


//PLUGIN

public class PluginA
{
        public PluginA()
        {
            //somehow subscribe to mainforms onProcessingCompleted with callback myCallback()
        }

        public void myCallback(object sender)
        {
        }


}

Я прочиталэтот сайт: http://www.javaworld.com/javaqa/2000-08/01-qa-0804-events.html?page=1

Они ссылаются на реализацию всего «списка подписки» вручную.Но код не полный пример, и я настолько привык к c #, что мне трудно понять, как я могу сделать это в Java.

У кого-нибудь есть рабочий пример этого, который я мог видеть?

спасибо
Стефани

1 Ответ

16 голосов
/ 21 января 2011

В Java у вас нет делегатов функций (фактически ссылки на методы);Вы должны передать весь класс, реализующий определенный интерфейс.Например,

class Producer {
  // allow a third party to plug in a listener
  ProducerEventListener my_listener;
  public void setEventListener(ProducerEventListener a_listener) {
    my_listener = a_listener;
  }

  public void foo() {
    ...
    // an event happened; notify the listener
    if (my_listener != null) my_listener.onFooHappened(new FooEvent(...));
    ...
  }
}


// Define events that listener should be able to react to
public interface ProducerEventListener {
  void onFooHappened(FooEvent e);
  void onBarOccured(BarEvent e);
  // .. as many as logically needed; often only one
}


// Some silly listener reacting to events
class Consumer implements ProducerEventListener {
  public void onFooHappened(FooEvent e) {
    log.info("Got " + e.getAmount() + " of foo");
  }
  ...
}

...
someProducer.setEventListener(new Consumer()); // attach an instance of listener

Часто у вас есть тривиальные слушатели, которые вы создаете с помощью анонимных классов:

someProducer.setEventListener(new ProducerEventListener(){
  public void onFooHappened(FooEvent e) {
    log.info("Got " + e.getAmount() + " of foo");
  }    
  public void onBarOccured(BarEvent e) {} // ignore
});

Если вы хотите разрешить много слушателей на событие (как, например, компоненты GUI)Вы управляете списком, который обычно хотите синхронизировать, и имеете для его управления addWhateverListener и removeWhateverListener.

Да, этот является безумно громоздким.Твои глаза не лгут тебе.

...