ковариация / противодействие

Предположим, у меня есть:

class Event {}
class DoorBell extends Event {}
class PhoneCall extends Event {}
class EventGenerator {
    static Event getEvent() {
         if (today.isSunday())
            return new DoorBell()
         else 
            return new PhoneCall();
    }
}
class EventHandler {    
    void HandleEvent(DoorBell doorBell) { answer door; }
    void HandleEvent(PhoneCall phoneCall) { answer phone; }
    void consumeEvent() {
         Event e = EventGenerator.getEvent();
         HandleEvent(e);
    }
}

HandleEvent (e) не компилируется, поскольку HandleEvent (Event) не определен. Есть ли решение для этого? Или мне нужно спросить е, что это за мероприятие?


person Shmoopy    schedule 16.12.2012    source источник
comment
Похоже, вы пытаетесь заново изобрести алгебраические типы данных и сопоставление с образцом. Ваши void HandleEvents - это просто статические перегрузки, которые отправляются с помощью информации статического типа, поэтому они не подходят. Для желаемого поведения вы должны спросить тип события с is или использовать некоторые тяжелые шаблоны отправки, такие как посетитель. Также подумайте о переходе на Scala.   -  person aemxdp    schedule 16.12.2012
comment
Похоже, работа для шаблона посетителя. Недавно я попытался ответить на аналогичный вопрос, возможно, он содержит некоторые интересные идеи, возможно, не является ответом, но заслуживает рассмотрения.   -  person Edwin Dalorzo    schedule 16.12.2012


Ответы (1)


Обычная идиома - передать событие и позволить полиморфизму сделать все за вас.

Я не вижу ценности в вашем EventHandler классе без какого-либо поведения. Ваш дизайн в том виде, в каком он сформулирован, не дает никаких полиморфных преимуществ. Вот почему вам нужно проверять типы. Лучше иметь что-то вроде этого:

public interface EventHandler {
    void handle(Event event);
}

Шаблон посетителя (также известный как «двойная отправка») может быть хорошим способом справиться с этой ситуацией.

Или вы можете попробовать дженерики:

public class EventHandler {
   public <T> void consumeEvent(T event) {
       // handler code here, dependent on T
   }
}

Я не знаю, есть ли в JDK 7 что-то новое, что может вам помочь. Прости; Я все еще застрял на JDK 6.

person duffymo    schedule 16.12.2012