© Excellent backgrounds/Shutterstock.com
Reaktive Programmierung mit Java

Reaktive Abkürzung


Überall ist es zu lesen und zu hören, das Thema Reactive. Meistens im Zusammenhang mit einem Framework, das dem Entwickler viele und mächtige Möglichkeiten an die Hand gibt. Es sorgt allerdings auch dafür, dass er eine weitere Abhängigkeit in seinem Projekt vorfindet. Muss das sein? Nein, hier kann man sehr oft schon mit Core Java zum Ziel kommen, ohne Unmengen an Quelltext zu erzeugen.

Vereinfacht lässt sich sagen, dass es sich hierbei um alle möglichen Ausprägungen des Observer-Patterns handelt. Genau an dieser Stelle werden viele Leser aufschreien, die sich schon damit beschäftigt haben. Jedoch sehen wir uns das erst einmal ganz einfach an. Das Grundprinzip ist, dass der Aufrufer nicht solange wartet, bis das Ergebnis berechnet worden ist. Es wird die Aufgabe formuliert und der nächsten Stufe übergeben. Wenn dies geschehen ist, wird sich diese schon zurückmelden. Im ersten Schritt bedeutet das, dass ich nicht selbst den Aufruf starte, sondern er gestartet wird. Schon sind wir beim Observer-Pattern. Die verarbeitende Einheit meldet sich beim Produzenten von Informationseinheiten an. Ist eine Informationseinheit bereit, verarbeitet zu werden, werden die Listener explizit mit diesem Wert aufgerufen. Der jeweilige Listener wiederum verarbeitet sein eigenes Ergebnis auf die gleiche Art und Weise und liefert es dann auch aus. Schon haben wir eine beliebig lange Kette an Operatoren, die aufeinander aufbauend ein Ergebnis berechnen.

Listing 1: Wrapper um eine „Map<KEY, Consumer<VALUE>>“

java public class Observable<KEY, VALUE> { private final Map<KEY, Consumer<VALUE>> listeners = new ConcurrentHashMap<>(); public void register(KEY key , Consumer<VALUE> listener) { listeners.put(key , listener); } public void unregister(KEY key) { listeners.remove(key);} public void sendEvent(VALUE event) { listeners.values().forEach(c -> c.accept(event)); } }

Implementieren wir als Erstes eine einfache Version des Observer-Patterns. Dahinter verbirgt sich nichts anderes als ein Wrapper um eine Map<KEY, Consumer<VALUE>> (Listing 1). Die Map selbst wird mittels ConcurrentHashMap realisiert, damit wir zumindest hier keine Nebenläufigkeitsprobleme bekommen. Können wir doch nicht vorhersehen, wie viele unterschiedliche Threads zu welchem Zeitpunkt Ereignisse erzeugen werden. Ob das reichen wird? Wir kommen später noch dazu. Unter einem Schlüssel kann sich ein Verbraucher registrieren und auch selbst wieder entfernen, sobald er keine weiteren Events mehr empfangen möchte. Wird ein...

Neugierig geworden?

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang