Реализация шаблона события домена в Java?

Я ищу простую Java-реализацию шаблона и инфраструктуры доменных событий Уди Дахана, как подробно описано в эта статья.

Это довольно просто, и я реализовал свою собственную интерпретацию, однако я новичок в Java и не хочу быть укушенным какими-либо ошибками из-за неопытности в языке.

Единственная реализация Java, которую я нашел, находится в Jdon Framework, но она слишком тяжеловесна для моего текущего уровня знаний. мой проект.

Спасибо!


person HolySamosa    schedule 18.04.2012    source источник


Ответы (2)


Я некоторое время искал решение той же проблемы в Java EE. Я просмотрел Axon и jdon (страница тоже не сулит ничего хорошего :)). Оба связаны с Event Sourcing, которые я не мог «продать» своим работодателям/клиентам. Я хотел иметь события домена, так как я очень привык к ним в проектах .NET/C#. Итак, я пришел к следующему...

Я использовал аналогичный статический объект DomainEvents, чтобы предоставить мне доступ к механизму публикации без фактической утечки сведений о реализации во всех объектах модели предметной области. Итак, звонки примерно такие:

DomainEvents.fire(new MySampleEvent(...some params...));

Шаблон и механизм, доступные в спецификации CDI, — это События с @Observes которые позволяют вам реагировать на определенные события в обычных bean-компонентах со всеми доступными службами. Это похоже на то, к чему я привык при использовании DI-фреймворков, таких как Castle Windsor, где я может регистрировать универсальные обработчики по интерфейсу. Итак, у меня есть наблюдатели (обработчики, слушатели, называйте их как угодно). Пример:

@Stateless
public class MySampleEventObserver {

  public void listen(@Observes MySampleEvent event) {
    ...
    doSomethingWithEvent();
  }
}

Теперь о публикации (запуске в CDI). Поскольку нет возможности получить доступ к CDI в сущностях (не без оснований!), я решил использовать JNDI и BeanManager. Я использовал JNDI, чтобы получить BeanManager и использовать его метод fireEvent. Чтобы поместить разрешение bean-менеджера (как см. здесь) в коде:

public class BeanHelper {
  public static BeanManager getBeanManager() {
    try {
        InitialContext initialContext = new InitialContext();
        return (BeanManager) initialContext.lookup("java:comp/BeanManager");
    } catch (NamingException e) {
        e.printStackTrace();
        return null;
    }
  }

}

Последним шагом является сам объект DomainEvents:

public class DomainEvents {

  private static boolean mNopMode = false;

  public static void setNopMode() {
    mNopMode = true;
  }

  public static void reset() {
    mNopMode = false;
  }

  public static <TDomainEvent> void fire(TDomainEvent event) {
    if (mNopMode) {
        return;
    }
    BeanManager manager = BeanHelper.getBeanManager();

    manager.fireEvent(event);
  }

}

Части setNopMode и reset предназначены для тестирования, когда нет контекста. Ручное издевательство в основном. Установите его в режим работы NOP перед юнит-тестами и сбросьте после них.

Отлично работает как POC. Не знаю, есть ли какие-то серьезные ограничения на его использование. Я оставляю асинхронные взаимодействия шины и аналогичную реализацию слушателей.

Буду рад любым комментариям.

person jl.    schedule 12.04.2013

В настоящее время я рассматриваю возможность использования Googles Guava EventBus, чтобы сделать что-то похожее на статья "Спасение", на которую вы ссылаетесь.

Использование аналогично «Как вызывать события домена» будет выглядеть примерно так, почти так же, как в статье:

public class Customer
{
    public void DoSomething()
    {
        MyEventBus.post(new CustomerBecamePreferred() { Customer = this });
    }
}

Я не знаю, считаете ли вы это «реализацией шаблона событий домена Уди Дахана».

Не требует реализации каких-либо интерфейсов; обработчики событий отмечены аннотациями, а класс зарегистрирован в EventBus с помощью MyEventBus.register(aListenerObject)

person Stephen P    schedule 18.04.2012
comment
Спасибо, Стивен, это довольно круто - я не знал о гуаве. Я действительно стараюсь, чтобы мой домен не знал о деталях реализации, но я подумаю о Guava EventBus. Возможно, я мог бы обернуть EventBus, чтобы скрыть реализацию от моего домена... - person HolySamosa; 19.04.2012
comment
Да @HolySamosa - я собираюсь обернуть его, когда вставлю, но оставьте для него простой интерфейс register() и post(). - person Stephen P; 19.04.2012
comment
Я предполагаю, что вы просто собираетесь сохранить аннотацию подписки Guava в своей модели домена? Мне нравится идея использования аннотации для привязки подписок, но я бы не хотел, чтобы такая деталь реализации проскользнула в мою красивую, чистую модель предметной области. - person HolySamosa; 19.04.2012