Commit 3357f896 authored by Julien SADAOUI's avatar Julien SADAOUI
Browse files

feat: readme

parent 153b2d7d
# Coding Dojo : RX Java
Bienvenue dans ce **Coding Dojo** ciblé sur l'usage de la programmation réactive, en utilisant le projet **RX Java 2**.
RX Java 2 est une librairie implémentant le paradigme de la programmation réactive. Dans ce **Coding Dojo**, vous apprendrez comment utiliser **RX Java 2**, les concepts, les opérateurs and les bonnes pratiques.
## Frameworks
Les frameworks utilisés pour ce coding dojo sont nombreux. Ci-dessous une liste des principaux :
* Java 11
* RX Java 2.2.4
* JUnit 5
* Lombok 1.18.4
* SLF4J
* Logback
* Etc.
## Enoncé
### A. Level 1
Création de flux de données
La classe **Observable** représente un flux de données. Les méthodes **just** ou **fromIterable** crée un flux à partir d'une collection d'objets. Les flux de données sont des chaînes de caractères dans cet exercice.
Si vous ne souscrivez pas au flux, rien ne se passe. La méthode **subscribe** déclare un **observer** consommant les données passées dans le flux. La souscription déclenche les étapes de traitement du flux.
### B. Level 2
Anatomie d'un flux de données (**stream**)
Un **Stream** est une séquence de données, potentiellement non limitée. Ces données peuvent être connues ou inconnues à sa création. Les flux sont des constructions asynchrones. Lorsque vous observez un flux, vous ne savez pas quand les données vont être émises.
Un **Observer** peut recevoir 3 types d'événements notifié par l'un des 3 méthodes suivantes:
- **onNext**: notifie à chaque fois qu'un élément est passé dans le flux
- **onComplete**: notifie la fin du flux. `onNext ne sera plus appelé
- **onError**: notifie qu'une erreur est arrivée. Le flux n'émettra plus d'éléments, **onComplete** n'est pas appelé.
RxJava met à disposition 3 méthodes à la disposition lors de la souscription.
- notifie les éléments : `stream.subscribe(item -> {});`
- notifie une erreur : `stream.subscribe(item -> {}, error -> {});`
- notifie la fin du flux : `stream.subscribe(item -> {}, error -> {}, () -> {});`
### C. Level 3
Cold Stream vs HotStream.
Nous allons aborder un concept clé dans la programmation. Il s'agit des flux qui peuvent-être froid (**Cold Stream**) ou chaud (**HotStream**).
Un **Cold Stream** recommence au début du flux pour chaque consommateur (**subscriber/observer**). Chaque consommateur obtient la liste complète des éléments.
Contrairement à un **Cold Stream**, un **HotStream** envoie les mêmes éléments à tous les consommateurs. Si un consommateur souscrit après le début de l'émission du flux, il ne receverra pas les éléments précédement émis.
\ No newline at end of file
package fr.ippon.codingdojo.reactive;
import fr.ippon.codingdojo.reactive.util.Helpers;
import fr.ippon.codingdojo.reactive.util.Log;
import io.reactivex.Observable;
import lombok.extern.slf4j.Slf4j;
......@@ -9,20 +10,9 @@ import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* Création de flux de données.
*
* La classe `Observable` représente un flux de données. Les méthodes `just` or `fromIterable` crée un flux
* à partir d'une collection d'objets. Les flux de données sont des chaînes de caractères dans cet exercice.
*
* Si vous ne souscrivez pas au flux, rien ne se passe. La méthode `subscribe` déclare un `observer` consommant
* les données passées dans le flux. La souscription déclenche les étapes de traitement du flux.
*
*/
@Slf4j
public class Level1 {
public static void main(String[] args) throws Exception {
exercise1();
......@@ -33,7 +23,7 @@ public class Level1 {
}
/**
* TODO: Créer un `Observable` de `Flash McQueen`, `Chick Hicks` and `The King` avec la méthode `Observable.just`
* Crée un `Observable` de `Flash McQueen`, `Chick Hicks` and `The King` avec la méthode `Observable.just`
*
* NOTE: sortie attendue
*
......@@ -41,7 +31,7 @@ public class Level1 {
* Flash McQueen
* Chick Hicks
* The King
* Done
* Completed
* Stop
*
* REMARQUE:
......@@ -51,13 +41,13 @@ public class Level1 {
log.info("Start Level1/Exercise1");
Observable.just("Flash McQueen", "Chick Hicks", "The King")
.subscribe(log::info, Log::error, Log::done);
.subscribe(log::info, Log::error, Log::completed);
log.info("Stop");
}
/**
* TODO: Créer un `Observable` à partir de la liste `data`
* Crée un `Observable` à partir de la liste `data`
*
* NOTE: sortie attendue
*
......@@ -65,7 +55,7 @@ public class Level1 {
* Flash McQueen
* Martin
* Sally Carrera
* Done
* Completed
* Stop
*
* REMARQUE:
......@@ -77,19 +67,19 @@ public class Level1 {
log.info("Start Level1/Exercise2");
Observable.fromIterable(data)
.subscribe(log::info, Log::error, Log::done);
.subscribe(log::info, Log::error, Log::completed);
log.info("Stop");
}
/**
* TODO: Créer à partir d'une tâche `Callable`, la tâche émet la valeur après 5 secondes.
* Crée un flux à partir d'une tâche `Callable`, la tâche émet la valeur après 5 secondes.
*
* NOTE: sortie attendue
*
* Start Level1/Exercise3
* Winner: Flash McQueen
* Done
* Completed
* Stop
*
* REMARQUE:
......@@ -98,25 +88,25 @@ public class Level1 {
private static void exercice3() {
Callable<String> callable = () -> {
nap(5, TimeUnit.SECONDS);
Helpers.sleep(5, TimeUnit.SECONDS);
return "Flash McQueen";
};
log.info("Start Level1/Exercise3");
Observable.fromCallable(callable)
.subscribe(winner -> log.info("Winner: {}", winner), Log::error, Log::done);
.subscribe(winner -> log.info("Winner: {}", winner), Log::error, Log::completed);
log.info("Stop");
}
/**
* TODO: Créer un `Observable` à partir d'un objet `Futre`, le résultat est émit par une tâche planifiée après 3 secondes.
* Crée un `Observable` à partir d'un objet `Future`, le résultat est émit par une tâche planifiée après 3 secondes.
*
* NOTE: sortie attendue
*
* Start Level1/Exercise4
* Winner: The king
* Done
* Completed
* Stop
*
* REMARQUE:
......@@ -128,17 +118,11 @@ public class Level1 {
log.info("Start Level1/Exercise4");
Observable.fromFuture(future)
.subscribe(winner -> log.info("Winner: {}", winner), Log::error, Log::done);
.subscribe(winner -> log.info("Winner: {}", winner), Log::error, Log::completed);
log.info("stop");
}
private static void nap(long delay, TimeUnit timeUnit) {
try {
Thread.sleep(timeUnit.toMillis(delay));
} catch (InterruptedException e) {
// ignore
}
}
}
......@@ -9,11 +9,11 @@ import java.util.List;
/**
* Anatomie d'un flux de données (stream).
*
* Un `Stream`est une séquence données, potentiellement non limitée. Ces données peuvent être connues ou inconnues
* Un `Stream` est une séquence données, potentiellement non limitée. Ces données peuvent être connues ou inconnues
* à son création. Les flux sont des constructions asynchrones. Lorsque vous observez un flux, vous ne savez pas
* quand les données vont être émises.
*
* Un `Observer` peut recevoir 3 types d'événements notifié par l'un des 3 méthodes suivantes:
* Un `Observer` peut recevoir 3 types d'événements notifié par l'une des 3 méthodes suivantes:
* - onNext: notifie à chaque fois qu'un élément est passé dans le flux
* - onComplete: notifie la fin du flux. `onNext ne sera plus appelé
* - onError: notifie qu'une erreur est arrivée. Le flux n'émettra plus d'éléments, `onComplete`n'est pas appelé.
......@@ -43,7 +43,7 @@ public class Level2 {
* Next: The King
* Next: Martin
* Next: Sally Carrera
* Done
* Completed
* Stop
*
*/
......@@ -54,7 +54,7 @@ public class Level2 {
log.info("Start Level2/Exercise1");
Observable.fromIterable(data)
.doOnNext(item -> log.info("Next: " + item))
.doOnComplete(Log::done)
.doOnComplete(Log::completed)
.subscribe();
log.info("Stop");
}
......@@ -109,7 +109,7 @@ public class Level2 {
* Next: Flash McQueen
* Next: The King
* Next: Chick Hicks
* Done
* Completed
* Stop
*
*/
......@@ -122,7 +122,7 @@ public class Level2 {
.subscribe(
item -> log.info("Next: " + item),
Log::error,
Log::done
Log::completed
);
log.info("Stop");
......@@ -132,7 +132,6 @@ public class Level2 {
* TODO: Depuis le début, nous utilisons des flux de données avec des valeurs fixes. Utiliser la méthodes `create`
* pour émettre un flux avec les valeurs `Flash McQueen`, `The King`, `Chick Hicks`, `Martin` et `Sally Carrera`.
*
*
* NOTE: sortie attendue
*
* Start Level2/Exercise2
......@@ -141,14 +140,14 @@ public class Level2 {
* Next: Chick Hicks
* Next: Martin
* Next: Sally Carrera
* Done
* Completed
* Stop
*
*/
public static void exercise4() {
log.info("Start Level2/Exercise4");
Observable<String> stream = Observable.create(subscriber -> {
Observable<String> observable = Observable.create(subscriber -> {
subscriber.onNext("Flash McQueen");
subscriber.onNext("The King");
......@@ -159,13 +158,13 @@ public class Level2 {
subscriber.onComplete();
});
stream.subscribe(
observable.subscribe(
item -> log.info("Next: " + item),
Log::error,
Log::done
Log::completed
);
log.info("Stop");
}
}
package fr.ippon.codingdojo.reactive;
import io.reactivex.Maybe;
import io.reactivex.Single;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Level4 {
public static void main(String[] args) {
//TODO: créer un flux émettant une valeur
Single.just("Superman")
.doOnSuccess(s -> log.info("Hello " + s))
.subscribe();
//
// Completable
Maybe.just("Superman")
.subscribe(
name -> System.out.println("[A] Received " + name),
Throwable::printStackTrace,
() -> System.out.println("[A] Completed")
);
Maybe.empty()
.subscribe(
name -> System.out.println("[B] Received " + name + " (not called)"),
Throwable::printStackTrace,
() -> System.out.println("[B] Completed")
);
}
}
......@@ -11,7 +11,7 @@ public class Log {
log.error(throwable.getMessage(), throwable);
}
public void done() {
log.info("Done");
public void completed() {
log.info("Completed");
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment