Проблема проектирования с механизмом «Событие / действие», Java универсальных шаблонов - PullRequest
0 голосов
/ 07 августа 2020

У меня проблема с моим текущим дизайном механизма событий / действий. Есть множество событий, которые можно выделить по определенным критериям. Это приводит к иерархии классов.

public interface Event , public abstract class EventCategory implements Event и фактическому событию, например, public class ActualEvent extends EventCategory . Затем есть Действия, которые могут выполнять операции на основе данного события.

public interface Action<T extends Event> {
  void execute(T event);
}

и фактическое действие ActualAction<T extends EventCategory> implements Action<T> . Теперь есть фабрики, которые генерируют указанные c экземпляры,

public interface ActionFactory<T extends Event> {
  Action<T> create(String actionData);
}

public class ActualActionFactory implements ActionFactory<EventCategory> {
  @Override 
  Action<T> create(String actionData);
}

Наконец, есть EventConsumers, каждый из которых имеет одно действие и будет обрабатывать возникновение событий и будет выполнять созданное действие.

public interface EventConsumer<T extends Event> {
  void handleEvent(T event);
}

public interface EventConsumerFactory<T extends Event> {
  EventConsumer<T> create(String data, Action<T> action);
}

Класс оркестратора, который содержит все ActionFactories и делегирует вызовы create

public class Orchestrator {
 private final List<ActionFactory<? extends Event>> factories = Lists.newArrayList();
 private final List<EventConsumerFactories<? extends Event>> consumerFactories = Lists.newArrayList();
 
 public void createAction(String actionData) {
   for (ActionFactory<? extends Event> factory : factories) {
     Action<? extends Event> action = factory.create(actionData);
     if (action != null) {
       consumerFactories.forEach(cf -> cf.create(null, action));
     }
 }

Я борюсь с последней частью. Если ввести действие, как указано выше, Action<? extends Event> вызов create для consumerFactories выдаст сообщение «Обязательно. , при условии ".

В чем проблема с моей иерархией классов или границами шаблона? Если использовать необработанные типы для действия в этом месте, все работает, и действия выполняются для настроенных событий. Но я бы хотел избавиться от сырые типы.

Спасибо за вашу помощь!

С уважением, Андреас

Редактировать: добавление кода, как фабрики регистрируются

public interface EventConsumerFactory<T extends Event> {
  EventConsumer<T> create(String consumerData, Action<? super Event> action);
}
public class ActualEventConsumerFactory implements EventConsumerFactory<ActualEvent>  {
}

Регистрация Orchestrator

  void registerConsumerFactory(ConsumerFactory<? super Event> factory) {
    this.consumerFactories.add(factory);
   }

1 Ответ

1 голос
/ 07 августа 2020

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

Оба EventConsumer и Action принимают экземпляры T: они потребители. Таким образом, вы не хотите объявлять их с помощью границ extends, потому что вы не сможете передать им ничего (кроме буквального null).

Код компилируется, если вы измените эти границы на super:

interface EventConsumerFactory<T extends Event> {
  EventConsumer<T> create(String data, Action<? super T> action);
                                             // here
}

class Orchestrator {
  private final List<ActionFactory<? super Event>> factories = Lists.newArrayList();
                                  // here
  private final List<EventConsumerFactory<? super Event>> consumerFactories = Lists.newArrayList();
                                         // here

  public void createAction(String actionData) {
    for (ActionFactory<? super Event> factory : factories) {
                      // here
      Action<? super Event> action = factory.create(actionData);
            // here
      if (action != null) {
        consumerFactories.forEach(cf -> cf.create(null, action));
      }
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...