21.04.2021
EventBus - Example
EventBus.java
package com.sowas.eventbus;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
/**
* Simple event bus implementation.
* Subscribe for and fire events.
*/
public enum EventBus {
INSTANCE;
private final Map> subscribers = new ConcurrentHashMap<>();
/**
* Subscribe to an event type
*
* @param subscriber The subscriber which will consume the events.
* @param eventClass The event class, can be a super class of Event.
*/
public void subscribe(ISubscriber subscriber, Class eventClass) {
Objects.requireNonNull(subscriber, "subscriber");
Objects.requireNonNull(eventClass, "eventClass");
subscribers.put(subscriber, eventClass);
}
/**
* Unsubscribe from all event types.
*
* @param subscriber the subscriber to unsubscribe.
*/
public void unsubscribe(ISubscriber subscriber) {
Objects.requireNonNull(subscriber, "subscriber");
subscribers.remove(subscriber);
}
/**
* Publish an event to all subscribers for exactly this event type.
*
* @param event the event.
*/
public void fire(Event event) {
subscribers.forEach((s, e) -> {
Class> clazz;
try {
clazz = Class.forName(e.getName());
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
return;
}
if (clazz.isInstance(event)) {
s.handleEventfired(event);
}
});
}
}
ISubscriber.java
package com.sowas.eventbus;
public interface ISubscriber {
public void handleEventfired(Event event);
}
Event.java
package com.sowas.eventbus;
public class Event {
private Object data;
public Object getData() {
return data;
}
public Event(Object data) {
this.data = data;
}
}
EventBusTest.java
package com.sowas.eventbus;
import static org.junit.Assert.assertEquals;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* Test class for the EventBus.
*/
public class EventBusTest {
int receivedEventsCount;
/**
* Tests the subscribing for Event.
* All(!) Events should be handled.
*/
@Test
public void testSubscribeEvent() {
ISubscriber subscriber = new ISubscriber() {
@Override
public void handleEventfired(Event event) {
receivedEventsCount++;
}
};
EventBus.INSTANCE.subscribe(subscriber, Event.class);
receivedEventsCount = 0;
EventBus.INSTANCE.fire(new Event(null));
EventBus.INSTANCE.fire(new ExtendedEvent(null));
assertEquals(2, receivedEventsCount);
EventBus.INSTANCE.unsubscribe(subscriber);
}
/**
* Tests the subscribing for Event.
* Only ExtendedEvents should be handled.
*/
@Test
public void testSubscribeDummyEvent() {
ISubscriber subscriber = new ISubscriber() {
@Override
public void handleEventfired(Event event) {
receivedEventsCount++;
}
};
EventBus.INSTANCE.subscribe(subscriber, ExtendedEvent.class);
receivedEventsCount = 0;
EventBus.INSTANCE.fire(new Event(null));
EventBus.INSTANCE.fire(new ExtendedEvent(null));
assertEquals(1, receivedEventsCount);
EventBus.INSTANCE.unsubscribe(subscriber);
}
/**
* An Event extended from Event.
*/
class ExtendedEvent extends Event {
public ExtendedEvent(Object data) {
super(data);
}
}
}