improvement: EventAggregator now considers Event-Type (#1933)

* Implemented more granular registration of observers with HashMap;
Key: Event, Value: List of Observers registered for the event;

* Edited constructors and super calls of all EventEmitter extenders

* Edited constructor calls in App.java

* Edited EventEmitterTest

* Added new white walkers event, scout emits at wednesday, varys observes and emits at saturday

* Added white walkers event to KingsHandTest.java

* Varys now passes events

* Corrected some indentation levels and added curly braces to if statements

* Corrected some styling

* Switched lines in App.java,
added javadoc to registerObserver

* Fixed some indents, added param comments
This commit is contained in:
Leisterbecker 2021-12-23 19:43:36 +01:00 committed by GitHub
parent 4588e09939
commit df73d80365
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 81 additions and 30 deletions

View File

@ -49,13 +49,28 @@ public class App {
public static void main(String[] args) {
var kingJoffrey = new KingJoffrey();
var kingsHand = new KingsHand(kingJoffrey);
var kingsHand = new KingsHand();
kingsHand.registerObserver(kingJoffrey, Event.TRAITOR_DETECTED);
kingsHand.registerObserver(kingJoffrey, Event.STARK_SIGHTED);
kingsHand.registerObserver(kingJoffrey, Event.WARSHIPS_APPROACHING);
kingsHand.registerObserver(kingJoffrey, Event.WHITE_WALKERS_SIGHTED);
var varys = new LordVarys();
varys.registerObserver(kingsHand, Event.TRAITOR_DETECTED);
varys.registerObserver(kingsHand, Event.WHITE_WALKERS_SIGHTED);
var scout = new Scout();
scout.registerObserver(kingsHand, Event.WARSHIPS_APPROACHING);
scout.registerObserver(varys, Event.WHITE_WALKERS_SIGHTED);
var baelish = new LordBaelish(kingsHand, Event.STARK_SIGHTED);
var emitters = List.of(
kingsHand,
new LordBaelish(kingsHand),
new LordVarys(kingsHand),
new Scout(kingsHand)
baelish,
varys,
scout
);
Arrays.stream(Weekday.values())

View File

@ -31,6 +31,7 @@ import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public enum Event {
WHITE_WALKERS_SIGHTED("White walkers sighted"),
STARK_SIGHTED("Stark sighted"),
WARSHIPS_APPROACHING("Warships approaching"),
TRAITOR_DETECTED("Traitor detected");

View File

@ -23,31 +23,48 @@
package com.iluwatar.event.aggregator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* EventEmitter is the base class for event producers that can be observed.
*/
public abstract class EventEmitter {
private final List<EventObserver> observers;
private final Map<Event, List<EventObserver>> observerLists;
public EventEmitter() {
observers = new LinkedList<>();
observerLists = new HashMap<>();
}
public EventEmitter(EventObserver obs) {
public EventEmitter(EventObserver obs, Event e) {
this();
registerObserver(obs);
registerObserver(obs, e);
}
public final void registerObserver(EventObserver obs) {
observers.add(obs);
/**
* Registers observer for specific event in the related list.
*
* @param obs the observer that observers this emitter
* @param e the specific event for that observation occurs
* */
public final void registerObserver(EventObserver obs, Event e) {
if (!observerLists.containsKey(e)) {
observerLists.put(e, new LinkedList<>());
}
if (!observerLists.get(e).contains(obs)) {
observerLists.get(e).add(obs);
}
}
protected void notifyObservers(Event e) {
observers.forEach(obs -> obs.onEvent(e));
if (observerLists.containsKey(e)) {
observerLists
.get(e)
.forEach(observer -> observer.onEvent(e));
}
}
public abstract void timePasses(Weekday day);

View File

@ -31,8 +31,8 @@ public class KingsHand extends EventEmitter implements EventObserver {
public KingsHand() {
}
public KingsHand(EventObserver obs) {
super(obs);
public KingsHand(EventObserver obs, Event e) {
super(obs, e);
}
@Override
@ -42,6 +42,5 @@ public class KingsHand extends EventEmitter implements EventObserver {
@Override
public void timePasses(Weekday day) {
// NOP
}
}

View File

@ -31,8 +31,8 @@ public class LordBaelish extends EventEmitter {
public LordBaelish() {
}
public LordBaelish(EventObserver obs) {
super(obs);
public LordBaelish(EventObserver obs, Event e) {
super(obs, e);
}
@Override

View File

@ -23,16 +23,19 @@
package com.iluwatar.event.aggregator;
import lombok.extern.slf4j.Slf4j;
/**
* LordVarys produces events.
*/
public class LordVarys extends EventEmitter {
@Slf4j
public class LordVarys extends EventEmitter implements EventObserver {
public LordVarys() {
}
public LordVarys(EventObserver obs) {
super(obs);
public LordVarys(EventObserver obs, Event e) {
super(obs, e);
}
@Override
@ -41,4 +44,10 @@ public class LordVarys extends EventEmitter {
notifyObservers(Event.TRAITOR_DETECTED);
}
}
@Override
public void onEvent(Event e) {
notifyObservers(e);
}
}

View File

@ -31,8 +31,8 @@ public class Scout extends EventEmitter {
public Scout() {
}
public Scout(EventObserver obs) {
super(obs);
public Scout(EventObserver obs, Event e) {
super(obs, e);
}
@Override
@ -40,5 +40,8 @@ public class Scout extends EventEmitter {
if (day == Weekday.TUESDAY) {
notifyObservers(Event.WARSHIPS_APPROACHING);
}
if (day == Weekday.WEDNESDAY) {
notifyObservers(Event.WHITE_WALKERS_SIGHTED);
}
}
}

View File

@ -31,6 +31,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
@ -46,7 +47,7 @@ abstract class EventEmitterTest<E extends EventEmitter> {
/**
* Factory used to create a new instance of the test object with a default observer
*/
private final Function<EventObserver, E> factoryWithDefaultObserver;
private final BiFunction<EventObserver, Event, E> factoryWithDefaultObserver;
/**
* Factory used to create a new instance of the test object without passing a default observer
@ -67,7 +68,7 @@ abstract class EventEmitterTest<E extends EventEmitter> {
* Create a new event emitter test, using the given test object factories, special day and event
*/
EventEmitterTest(final Weekday specialDay, final Event event,
final Function<EventObserver, E> factoryWithDefaultObserver,
final BiFunction<EventObserver, Event, E> factoryWithDefaultObserver,
final Supplier<E> factoryWithoutDefaultObserver) {
this.specialDay = specialDay;
@ -129,8 +130,8 @@ abstract class EventEmitterTest<E extends EventEmitter> {
final var observer2 = mock(EventObserver.class);
final var emitter = this.factoryWithoutDefaultObserver.get();
emitter.registerObserver(observer1);
emitter.registerObserver(observer2);
emitter.registerObserver(observer1, event);
emitter.registerObserver(observer2, event);
testAllDays(specialDay, event, emitter, observer1, observer2);
}
@ -146,9 +147,9 @@ abstract class EventEmitterTest<E extends EventEmitter> {
final var observer1 = mock(EventObserver.class);
final var observer2 = mock(EventObserver.class);
final var emitter = this.factoryWithDefaultObserver.apply(defaultObserver);
emitter.registerObserver(observer1);
emitter.registerObserver(observer2);
final var emitter = this.factoryWithDefaultObserver.apply(defaultObserver, event);
emitter.registerObserver(observer1, event);
emitter.registerObserver(observer2, event);
testAllDays(specialDay, event, emitter, defaultObserver, observer1, observer2);
}

View File

@ -55,7 +55,11 @@ class KingsHandTest extends EventEmitterTest<KingsHand> {
@Test
void testPassThrough() throws Exception {
final var observer = mock(EventObserver.class);
final var kingsHand = new KingsHand(observer);
final var kingsHand = new KingsHand();
kingsHand.registerObserver(observer, Event.STARK_SIGHTED);
kingsHand.registerObserver(observer, Event.WARSHIPS_APPROACHING);
kingsHand.registerObserver(observer, Event.TRAITOR_DETECTED);
kingsHand.registerObserver(observer, Event.WHITE_WALKERS_SIGHTED);
// The kings hand should not pass any events before he received one
verifyZeroInteractions(observer);

View File

@ -34,7 +34,9 @@ class ScoutTest extends EventEmitterTest<Scout> {
* Create a new test instance, using the correct object factory
*/
public ScoutTest() {
super(Weekday.TUESDAY, Event.WARSHIPS_APPROACHING, Scout::new, Scout::new);
super(Weekday.TUESDAY, Event.WARSHIPS_APPROACHING, Scout::new, Scout::new);
}
}