Skip to content

Commit 451cc4e

Browse files
committed
adds event emitter pattern
1 parent c3c6e28 commit 451cc4e

File tree

2 files changed

+118
-1
lines changed

2 files changed

+118
-1
lines changed

.vitepress/sidebars/java.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ export const java = [
9090
{ text: 'Singleton pattern', link: '/java/singleton-pattern' },
9191
{ text: 'Adapter pattern', link: '/java/adapter-pattern' },
9292
{ text: 'Facade pattern', link: '/java/facade-pattern' },
93-
{ text: 'Mediator pattern', link: '/java/mediator-pattern' }
93+
{ text: 'Mediator pattern', link: '/java/mediator-pattern' },
94+
{ text: 'Event emitter', link: '/java/event-emitter' }
9495
]
9596
}
9697
]

src/java/event-emitter.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Event emitter
2+
3+
The event emitter pattern is one way of implementing an event driven program. It
4+
enables a list of listener functions to respond to certain events within the
5+
program, such as clicking a button.
6+
7+
## Event emitter class
8+
9+
We will create a class which implements two methods:
10+
11+
- `.on(event, listener)` which adds the function `listener` to the list of
12+
listeners
13+
14+
- `.emit(event, value)` which loops through the listeners and executes each one,
15+
passing `value` as an argument
16+
17+
```java
18+
import java.util.ArrayList;
19+
import java.util.HashMap;
20+
import java.util.List;
21+
import java.util.Map;
22+
23+
class EventEmitter {
24+
private Map<String, List<EventListener>> events;
25+
26+
public EventEmitter() {
27+
this.events = new HashMap<>();
28+
}
29+
30+
public void on(String event, EventListener listener) {
31+
// Ensure the list of listeners exists for the event
32+
this.events.computeIfAbsent(event, k -> new ArrayList<>());
33+
34+
// Add the listener to the list
35+
this.events.get(event).add(listener);
36+
}
37+
38+
public void emit(String event, Object value) {
39+
// Get the list of listeners for the event, if it exists
40+
List<EventListener> listeners = this.events.getOrDefault(event, new ArrayList<>());
41+
42+
// Call each listener with the provided value
43+
for (EventListener listener : listeners) {
44+
listener.handle(value);
45+
}
46+
}
47+
48+
@FunctionalInterface
49+
interface EventListener {
50+
void handle(Object value);
51+
}
52+
}
53+
54+
```
55+
56+
## Create a button
57+
58+
We'll create a button to extend the `EventEmitter` class, meaning it gets the
59+
`.on()` and `.emit()` methods it needs to manage its listeners.
60+
61+
```java
62+
class Button extends EventEmitter {
63+
private int count;
64+
65+
public Button() {
66+
this.count = 0;
67+
}
68+
69+
public void click() {
70+
this.count++;
71+
// Emit the "click" event with the current count
72+
this.emit("click", this.count);
73+
}
74+
}
75+
76+
```
77+
78+
## Attach listeners
79+
80+
Let's create some listener functions we want to execute whenever `'click'` is
81+
emitted by the button.
82+
83+
```java
84+
public class Main {
85+
public static void main(String[] args) {
86+
Button btn = new Button();
87+
88+
// Attach listener to submit form
89+
btn.on("click", value -> System.out.println("Form submitted."));
90+
91+
// Attach listener to show dialog with click count
92+
btn.on("click", value -> {
93+
int count = (int) value;
94+
System.out.println("You clicked me " + count + " times!");
95+
});
96+
97+
// Simulate button clicks
98+
btn.click();
99+
btn.click();
100+
btn.click();
101+
}
102+
}
103+
```
104+
105+
The output would look like this:
106+
107+
```console
108+
Form submitted.
109+
You clicked me 1 times!
110+
111+
Form submitted.
112+
You clicked me 2 times!
113+
114+
Form submitted.
115+
You clicked me 3 times!
116+
```

0 commit comments

Comments
 (0)