SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

デザインパターンを置き換えよう! Javaラムダ式によるシンプルコーディング

ラムダ式でObserverパターンで実装されたコードをシンプルにする ~ オブザーバオブジェクトはラムダ式によって簡潔に生成できる

デザインパターンを置き換えよう! Javaラムダ式によるシンプルコーディング 第3回


考察:やりたいことは「何か起きたら知らせてください」

 以上の例より、オブザーバオブジェクトは、ラムダ式によって簡潔に生成できることが分かります。

 前々回に紹介したCommandパターンの場合、前回に紹介したStrategyパターンの場合と同様に、ラムダ式を使うプログラム(リスト3)は、Observerパターンのプログラム(リスト2)から、構造は大きく変わっていません。実質的な差異は、ジョブオブザーバを生成するところで、ラムダ式を使っているということだけです。したがって、リスト3のプログラムもやはり、Observerパターンを採用しているとみなすことは可能です。

 しかしながら、リスト3の main メソッドで addObserver メソッドを呼び出しているところを読んで、わざわざ「ConcreteSubjectであるジョブ定義クラスのインスタンスにオブザーバオブジェクトを登録する」と理解する必要は薄いように思われます。ここで表現されていることは、「ジョブに何かが起きたらが知らせてください、とジョブ定義に頼む」というだけのことだからです。ラムダ式によって「知らせを受ける処理」がプログラムの式の中で表せるようになったため、あえて「オブザーバオブジェクト」のような概念を導入する必要が薄まった、といえるでしょう。

 「何かが起きたら知らせてください」という意図を素直に書けるようにするためには、 「 addObserver 」というメソッド名も再考したほうがよいかもしれません。例えば、リスト4のように 「 onJobUpdate 」というメソッド名であれば、「ジョブに何かが起きたら~」という気持ちが分かりやすくなるように思われます。

リスト4:メソッド名を変えてみる
// バックアップジョブの状態に変更があったらログ出力する
backupJobDefinition.onJobUpdate(backupJob -> {
    System.out.printf("[INFO] バックアップ: %s ステータス: %s%n",
            backupJob.getFileName(), backupJob.getStatus());
});

 念のために申し添えておくと、インタフェースのメソッド名の変更は、既存のプログラムを壊さないことを確かめながら、慎重に行われる必要があります。

 Observerの役割を果たすインタフェースは、関数的インタフェースであることが多いため、ジョブコントローラプログラムに限らず、そのインスタンス生成にラムダ式が使える可能性があります。例えば、リスト1で紹介したJavaFXの ChangeListener インタフェースも関数型インタフェースです。したがって、リスト1のプログラムは、ラムダ式を使ってリスト5のように書き換えられます。

リスト5:LambdaWindowSizeMonitor.java
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;

public class LambdaWindowSizeMonitor extends Application {

    /** 表示領域. */
    private final BorderPane pane = new BorderPane();

    /** ウィンドウのシーン. */
    private final Scene scene = new Scene(this.pane, 600, 400);

    /**
     * 表示領域にウィンドウサイズを表示する.
     */
    private void showSize() {
        String message = String.format("%s x %s", scene.getWidth(), scene.getHeight());
        pane.setCenter(new Label(message));
    }

    @Override
    public void start(Stage stage) {
        showSize();

        // ウィンドウサイズが変わったらサイズを表示し直す
        scene.widthProperty().addListener((prop, oldNum, newNum) -> showSize());
        scene.heightProperty().addListener((prop, oldNum, newNum) -> showSize());

        stage.setScene(scene);
        stage.setTitle("Lambda Window Size Monitor");
        stage.show();
    }

    public static void main(String[] args) {
        launch(LambdaWindowSizeMonitor.class, args);
    }
}

 リスト5では、ウィンドウサイズ変更の通知を受けて showSize メソッドを呼び出すオブザーバオブジェクトを、ラムダ式で生成して addListener メソッドに渡しています。「ウィンドウサイズが変わったら知らせてください、showSize メソッドでサイズを表示し直すから」という意図がより分かりやすく表現できているのではないでしょうか。

おわりに

 今回使ったジョブコントローラプログラムは、ジョブ定義がジョブを生成する箇所で、Template MethodパターンとFactory Methodパターンを組み合わせて使っています。この組み合わせは、現実のアプリケーションでもよく登場するものです。

 連載最終回となる次回は、今回のジョブコントローラプログラムを題材として、Template MethodパターンとFactory Methodパターンのラムダ式による書き換えを取り上げます。これまでに扱ったCommandパターン、Strategyパターン、Observerパターンと異なり、比較的大規模なプログラム構造の変更が必要となります。この書き換えを通じて、ラムダ式が活用できるようなプログラムの構造について理解が深められるはずです。

 それでは、最終回もお楽しみに。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
デザインパターンを置き換えよう! Javaラムダ式によるシンプルコーディング連載記事一覧

もっと読む

この記事の著者

宮川 拓(ミヤカワ タク)

日本Javaユーザーグループ幹事。東京のシステムインテグレータに勤務。Java VM上で動作する言語である「Kink」を開発中。相撲とアメリカ文学とスコティッシュポップを愛する。 ・ブログ: http://d.hatena.ne.jp/miyakawa_taku/ ・Twitter: @miyakawa_taku

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/8504 2015/03/12 21:10

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー