SE情報技術研究会’s blog

http://se-info-tech.connpass.com

2015-12-18 『Learning Reactive Programming with Java 8』 もくもく読書会(Chapter 2)の振り返り

Learning Reactive Programming With Java 8

Learning Reactive Programming With Java 8

Chapter 2: Using the Functional Constructions of Java 8

タイトルは「Java 8での関数的な構築の使用」というところか?

Introduction

関数型プログラミング

  • 小さい再利用可能な関数を使いながらプログラムを構築すること
  • プログラムのロジックは工程を明らかにした小さいもので複雑なアルゴリズムではない
  • 状態の使用を最低限に抑える
  • Java 8 よりラムダ式の使用が可能になり関数に関数を渡すことが可能になった

この章では下記のトピックを見ていく

Lambda in Java 8

Listが使えるObservable#map(Func1)のようなメソッドを実装するため、次のようなコードがあったとする。

interface Mapper<V, M> {
  M map<V value);
}
public static <V, M> List<M> map(List<V> list, Mapper<V, M> mapper){
    List<M> mapped = new ArrayList<M>(list.size());
    for(V v: list){
      mapped.add(mapper.map(v);
    }
    return mapped;
}

これをラムダ式を使わずに実装するには匿名クラスを使わなければならない。これは無駄な行とコードが多い。

また匿名クラス方法の問題の本質はアクションを渡しているのではなくオブジェクトを渡している点にあり、プログラムのすべきことを曖昧にしている。

ラムダ式を使うとシンプルになり、わかりやすくなる。

特にオブジェクトを渡す代わりにアクションが定義されたコードのブロックを渡すことで意図がはっきりする。

ラムダ式

メソッド参照/コンストラクタ参照の例

Functional interfaces in Java 8 and RxJava

Implementing the reactive sum example with lambda

※ ソースは本もしくは著者のGitHub参照

内容はChpter 1と同じだが、かなりシンプルでわかりやすくなる

※ メモ
  • 内容はChpter 1と同じと本ではあるがonCompleteで参照しているsumが見れなくなっている
  • Observable#createメソッドラムダ式で書くには引数のSubscriberの型を定義しないと型がStringではなくObjectになるためコンパイルエラーになる
    return Observable
        .create((Subscriber<? super String> subscriber) -> {

Pure functions and higher order functions

  • Rxjavaは多くの関数型プログラミングの考え方を導入している
  • より良いReactiveなアプリケーションを作るのに関数型の考え方を学ぶ必要がある

Pure functions

  • 戻り値が引数によってのみ決められる関数
  • 副作用がない
  • idempotence(冪等性べきとうせい) = 何度やっても結果が同じ
  • immutableなオブジェクトを使うことが重要

ただしimmutableなオブジェクトは毎回新しいインスタンスを作るのでメモリが足らなくなる可能性がある

それを避けるには同じオブジェクトを再利用したり、オブジェクトのライフサイクルを短くするなどしないといけない

Higher order functions

  • 関数を引数や戻り値に持つ関数
  • 高階関数の目的は関数を柔軟にすること
  • 同じ振舞を別の型の入力値に適用することが可能になる
  • ひとつの関数を使って振舞を変えることが可能
  • オブジェクト指向の場合、継承してOverrideしたりする必要があるが、関数型だと高階関数を使って同じ関数を違う引数で呼び、違う振舞を低位することができる。

RxJava and functional programming

  • RxJavaは純粋関数や高階関数などの関数型のコンセプトが重要である