Compare commits

...

6 Commits

Author SHA1 Message Date
allcontributors[bot]
850027c035 docs: update .all-contributorsrc [skip ci] 2021-12-23 18:44:43 +00:00
allcontributors[bot]
a9a82efc0e docs: update README.md [skip ci] 2021-12-23 18:44:42 +00:00
Leisterbecker
df73d80365 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
2021-12-23 20:43:36 +02:00
allcontributors[bot]
4588e09939 docs: add yuhangbin as a contributor for code (#1934)
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2021-12-23 18:11:48 +02:00
CharlieYu
69883196d2 improvement: Optimized NioReactor stop() (Reactor Pattern) (#1930)
* Optimized NioReactor stop()

* Optimized ThreadPoolDispatcher stop()
2021-12-23 18:10:17 +02:00
allcontributors[bot]
4dcc20b733 docs: add interactwithankush as a contributor for code (#1931)
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: Subhrodip Mohanta <hello@subho.xyz>
Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2021-12-16 20:06:21 +05:30
14 changed files with 119 additions and 34 deletions

View File

@@ -1749,6 +1749,33 @@
"review", "review",
"code" "code"
] ]
},
{
"login": "interactwithankush",
"name": "interactwithankush",
"avatar_url": "https://avatars.githubusercontent.com/u/18613127?v=4",
"profile": "https://github.com/interactwithankush",
"contributions": [
"code"
]
},
{
"login": "yuhangbin",
"name": "CharlieYu",
"avatar_url": "https://avatars.githubusercontent.com/u/17566866?v=4",
"profile": "https://github.com/yuhangbin",
"contributions": [
"code"
]
},
{
"login": "Leisterbecker",
"name": "Leisterbecker",
"avatar_url": "https://avatars.githubusercontent.com/u/20650323?v=4",
"profile": "https://github.com/Leisterbecker",
"contributions": [
"code"
]
} }
], ],
"contributorsPerLine": 7, "contributorsPerLine": 7,

View File

@@ -10,7 +10,7 @@
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=coverage)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=coverage)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns)
[![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --> <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-192-orange.svg?style=flat-square)](#contributors-) [![All Contributors](https://img.shields.io/badge/all_contributors-195-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END --> <!-- ALL-CONTRIBUTORS-BADGE:END -->
<br/> <br/>
@@ -322,6 +322,9 @@ This project is licensed under the terms of the MIT license.
<td align="center"><a href="https://www.linkedin.com/in/abhinav-vashisth-06613b208/"><img src="https://avatars.githubusercontent.com/u/89785800?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Abhinav Vashisth</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=vashisthabhinav" title="Documentation">📖</a></td> <td align="center"><a href="https://www.linkedin.com/in/abhinav-vashisth-06613b208/"><img src="https://avatars.githubusercontent.com/u/89785800?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Abhinav Vashisth</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=vashisthabhinav" title="Documentation">📖</a></td>
<td align="center"><a href="http://no website"><img src="https://avatars.githubusercontent.com/u/47126749?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kevin</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/pulls?q=is%3Apr+reviewed-by%3AKevinyl3" title="Reviewed Pull Requests">👀</a></td> <td align="center"><a href="http://no website"><img src="https://avatars.githubusercontent.com/u/47126749?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kevin</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/pulls?q=is%3Apr+reviewed-by%3AKevinyl3" title="Reviewed Pull Requests">👀</a></td>
<td align="center"><a href="https://github.com/Shrirang97"><img src="https://avatars.githubusercontent.com/u/28738668?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Shrirang</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/pulls?q=is%3Apr+reviewed-by%3AShrirang97" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/iluwatar/java-design-patterns/commits?author=Shrirang97" title="Code">💻</a></td> <td align="center"><a href="https://github.com/Shrirang97"><img src="https://avatars.githubusercontent.com/u/28738668?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Shrirang</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/pulls?q=is%3Apr+reviewed-by%3AShrirang97" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/iluwatar/java-design-patterns/commits?author=Shrirang97" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/interactwithankush"><img src="https://avatars.githubusercontent.com/u/18613127?v=4?s=100" width="100px;" alt=""/><br /><sub><b>interactwithankush</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=interactwithankush" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/yuhangbin"><img src="https://avatars.githubusercontent.com/u/17566866?v=4?s=100" width="100px;" alt=""/><br /><sub><b>CharlieYu</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=yuhangbin" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/Leisterbecker"><img src="https://avatars.githubusercontent.com/u/20650323?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Leisterbecker</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=Leisterbecker" title="Code">💻</a></td>
</tr> </tr>
</table> </table>

View File

@@ -49,13 +49,28 @@ public class App {
public static void main(String[] args) { public static void main(String[] args) {
var kingJoffrey = new KingJoffrey(); 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( var emitters = List.of(
kingsHand, kingsHand,
new LordBaelish(kingsHand), baelish,
new LordVarys(kingsHand), varys,
new Scout(kingsHand) scout
); );
Arrays.stream(Weekday.values()) Arrays.stream(Weekday.values())

View File

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

View File

@@ -23,31 +23,48 @@
package com.iluwatar.event.aggregator; package com.iluwatar.event.aggregator;
import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* EventEmitter is the base class for event producers that can be observed. * EventEmitter is the base class for event producers that can be observed.
*/ */
public abstract class EventEmitter { public abstract class EventEmitter {
private final List<EventObserver> observers; private final Map<Event, List<EventObserver>> observerLists;
public EventEmitter() { public EventEmitter() {
observers = new LinkedList<>(); observerLists = new HashMap<>();
} }
public EventEmitter(EventObserver obs) { public EventEmitter(EventObserver obs, Event e) {
this(); 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) { 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); public abstract void timePasses(Weekday day);

View File

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

View File

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

View File

@@ -23,16 +23,19 @@
package com.iluwatar.event.aggregator; package com.iluwatar.event.aggregator;
import lombok.extern.slf4j.Slf4j;
/** /**
* LordVarys produces events. * LordVarys produces events.
*/ */
public class LordVarys extends EventEmitter { @Slf4j
public class LordVarys extends EventEmitter implements EventObserver {
public LordVarys() { public LordVarys() {
} }
public LordVarys(EventObserver obs) { public LordVarys(EventObserver obs, Event e) {
super(obs); super(obs, e);
} }
@Override @Override
@@ -41,4 +44,10 @@ public class LordVarys extends EventEmitter {
notifyObservers(Event.TRAITOR_DETECTED); 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() {
} }
public Scout(EventObserver obs) { public Scout(EventObserver obs, Event e) {
super(obs); super(obs, e);
} }
@Override @Override
@@ -40,5 +40,8 @@ public class Scout extends EventEmitter {
if (day == Weekday.TUESDAY) { if (day == Weekday.TUESDAY) {
notifyObservers(Event.WARSHIPS_APPROACHING); 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 static org.mockito.Mockito.verifyZeroInteractions;
import java.util.Objects; import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.junit.jupiter.api.Test; 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 * 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 * 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 * Create a new event emitter test, using the given test object factories, special day and event
*/ */
EventEmitterTest(final Weekday specialDay, final Event event, EventEmitterTest(final Weekday specialDay, final Event event,
final Function<EventObserver, E> factoryWithDefaultObserver, final BiFunction<EventObserver, Event, E> factoryWithDefaultObserver,
final Supplier<E> factoryWithoutDefaultObserver) { final Supplier<E> factoryWithoutDefaultObserver) {
this.specialDay = specialDay; this.specialDay = specialDay;
@@ -129,8 +130,8 @@ abstract class EventEmitterTest<E extends EventEmitter> {
final var observer2 = mock(EventObserver.class); final var observer2 = mock(EventObserver.class);
final var emitter = this.factoryWithoutDefaultObserver.get(); final var emitter = this.factoryWithoutDefaultObserver.get();
emitter.registerObserver(observer1); emitter.registerObserver(observer1, event);
emitter.registerObserver(observer2); emitter.registerObserver(observer2, event);
testAllDays(specialDay, event, emitter, observer1, observer2); testAllDays(specialDay, event, emitter, observer1, observer2);
} }
@@ -146,9 +147,9 @@ abstract class EventEmitterTest<E extends EventEmitter> {
final var observer1 = mock(EventObserver.class); final var observer1 = mock(EventObserver.class);
final var observer2 = mock(EventObserver.class); final var observer2 = mock(EventObserver.class);
final var emitter = this.factoryWithDefaultObserver.apply(defaultObserver); final var emitter = this.factoryWithDefaultObserver.apply(defaultObserver, event);
emitter.registerObserver(observer1); emitter.registerObserver(observer1, event);
emitter.registerObserver(observer2); emitter.registerObserver(observer2, event);
testAllDays(specialDay, event, emitter, defaultObserver, observer1, observer2); testAllDays(specialDay, event, emitter, defaultObserver, observer1, observer2);
} }

View File

@@ -55,7 +55,11 @@ class KingsHandTest extends EventEmitterTest<KingsHand> {
@Test @Test
void testPassThrough() throws Exception { void testPassThrough() throws Exception {
final var observer = mock(EventObserver.class); 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 // The kings hand should not pass any events before he received one
verifyZeroInteractions(observer); verifyZeroInteractions(observer);

View File

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

View File

@@ -96,9 +96,11 @@ public class NioReactor {
* @throws IOException if any I/O error occurs. * @throws IOException if any I/O error occurs.
*/ */
public void stop() throws InterruptedException, IOException { public void stop() throws InterruptedException, IOException {
reactorMain.shutdownNow(); reactorMain.shutdown();
selector.wakeup(); selector.wakeup();
reactorMain.awaitTermination(4, TimeUnit.SECONDS); if (!reactorMain.awaitTermination(4, TimeUnit.SECONDS)) {
reactorMain.shutdownNow();
}
selector.close(); selector.close();
LOGGER.info("Reactor stopped"); LOGGER.info("Reactor stopped");
} }

View File

@@ -64,6 +64,8 @@ public class ThreadPoolDispatcher implements Dispatcher {
@Override @Override
public void stop() throws InterruptedException { public void stop() throws InterruptedException {
executorService.shutdown(); executorService.shutdown();
executorService.awaitTermination(4, TimeUnit.SECONDS); if (executorService.awaitTermination(4, TimeUnit.SECONDS)) {
executorService.shutdownNow();
}
} }
} }