id:KenichiroMurata(@muraken720 )です。
皆さん、RxJava 使っていますか?
前回はVert.xのmod-rxvertxを使い、RxJavaによってCallback Hellから脱出する方法を説明しました。本記事は、せっかくなのでJava8のラムダを使ったらさらにどのようになるのか?を試してみた補足記事です。
目次は以下の通りです。
- 環境
- Java8 ラムダによってCallback Hellはいかに解決されたか
- まとめ
1. 環境
本記事で試した環境について説明します。
- Vert.x 2.1M1
- mod-rxvertx 1.0.0-beta2
- RxJava 0.15.1
- Java 1.8.0-ea(build 1.8.0-ea-b118)
- IntelliJ IDEA 13 CE
Java8を試すために、IntelliJ IDEA 13 CEを使いました。Java8をインストールし、IDEAを使う場合は以下のように初期化してください。
ken@vertx-test $ ./gradlew test ken@vertx-test $ ./gradlew copyModJson ken@vertx-test $ ./gradlew idea
2. Java8 ラムダによってCallback Hellはいかに解決されたか
まずは、通常のVert.xで書いた場合のコードのJava8 ラムダ版は次のようになります。例を分かりやすくするために、JSONメッセージの生成部などは外部メソッド化しました。
J8BusModVerticleTest.testSerialAction
@Test public void testSerialAction() { final EventBus eventBus = vertx.eventBus(); final ConcurrentMap<String, String> map = vertx.sharedData().getMap("muraken720.testexample"); JsonObject req1 = createAddRequest("@muraken720"); // リクエスト1 eventBus.send("muraken720.vertx.mod.testexample", req1, (Handler<Message<JsonObject>>) reply -> { assertEquals("ok", reply.body().getString("status")); assertEquals("@muraken720", map.get("name")); JsonObject req2 = createAddRequest("Kenichiro"); // リクエスト2 eventBus.send("muraken720.vertx.mod.testexample", req2, (Handler<Message<JsonObject>>) reply1 -> { assertEquals("ok", reply.body().getString("status")); assertEquals("Kenichiro", map.get("name")); JsonObject req3 = createAddRequest("Murata"); // リクエスト3 eventBus.send("muraken720.vertx.mod.testexample", req3, (Handler<Message<JsonObject>>) reply2 -> { assertEquals("ok", reply.body().getString("status")); assertEquals("Murata", map.get("name")); testComplete(); }); }); }); }
ラムダ式により、無名クラスの部分がスッキリしていますね。
それではこれをRxJavaを使ってコードを書くと次のようになります。
RxJ8BusModVerticleTest.testSerialAction
@Test public void testSerialAction() { final RxEventBus rxEventBus = new RxEventBus(vertx.eventBus()); final ConcurrentMap<String, String> map = vertx.sharedData().getMap("muraken720.testexample"); JsonObject req1 = createAddRequest("@muraken720"); // リクエスト1 Observable<RxMessage<JsonObject>> obs1 = rxEventBus.send("muraken720.vertx.mod.testexample", req1); Observable<RxMessage<JsonObject>> obs2 = obs1.flatMap(reply -> { assertEquals("ok", reply.body().getString("status")); assertEquals("@muraken720", map.get("name")); JsonObject req2 = createAddRequest("Kenichiro"); return rxEventBus.send("muraken720.vertx.mod.testexample", req2); }); // リクエスト2 Observable<RxMessage<JsonObject>> obs3 = obs2.flatMap(reply -> { assertEquals("ok", reply.body().getString("status")); assertEquals("Kenichiro", map.get("name")); JsonObject req3 = createAddRequest("Murata"); return rxEventBus.send("muraken720.vertx.mod.testexample", req3); }); // リクエスト3 obs3.subscribe(reply -> { assertEquals("ok", reply.body().getString("status")); assertEquals("Murata", map.get("name")); testComplete(); }); }
Java8のラムダ式を使うことにより、RxJavaのAction1、Function1といった無味乾燥なクラス名も登場しなくなり、非常にスッキリしました。コード自体も縦には長くなっていますが、ネストが深くならないことがよく分かると思います。
3 まとめ
いかかでしょうか?Java8のラムダを使うことで、Callback Hellから脱出するだけでなく、その記述方法のシンプルになることがご覧頂けたと思います。Java8の正式リリースは3月?だったと思いますが、そのJava8に向けて、RxJavaもVert.xもさらに進化していくと思います。今後どのようになるのか?を想像しながら、あれこれ試してみると面白いと思います。
See also
- Vert.x がいいね!(第1回:入門する) - Taste of Tech Topics
- Vert.x がいいね!(第2回:開発環境を構築する) - Taste of Tech Topics
- Vert.x がいいね!(第3回:Event LoopsとVerticle Instances) - Taste of Tech Topics
- Vert.x がいいね!(第4回:テストする) - Taste of Tech Topics
- RxJavaを使ってCallback Hellから脱出する( Vert.x がいいね!第5回 ) - Taste of Tech Topics
Acroquest Technologyでは、キャリア採用を行っています。
- 日頃勉強している成果を、Hadoop、Storm、NoSQL、HTML5/CSS3/JavaScriptといった最新の技術を使ったプロジェクトで発揮したい。
- 社会貢献性の高いプロジェクトに提案からリリースまで携わりたい。
- 書籍・雑誌等の執筆や対外的な勉強会の開催を通した技術の発信や、社内勉強会での技術情報共有により、技術的に成長したい。
- OSSの開発に携わりたい。
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
キャリア採用ページ