正式版のリリースが2014年3月18日に延期された Java8 の Lambda を今回も楽しんでみます。
いつものようにネットから情報を取得して少しコードを変えて動かしているだけの写経のようなことをやってます。
詳しいことは解らないけど慣れるってことが目的です!
今回はデザインパターンの一つである Template Method Pattern を Lambda を使って実装してみる試みです。
Template Method Pattern について知りたければグーグル先生に聞いてみたらいっぱい答えを教えてくれます。
Wikipedia では、Template Method パターン(テンプレート・メソッド・パターン)とは、GoF(Gang of Four; 4人のギャングたち)によって定義されたデザインパターンの1つである。
「振る舞いに関するパターン」に属する。Template Method パターンの目的は、ある処理のおおまかなアルゴリズムをあらかじめ決めておいて、
そのアルゴリズムの具体的な設計をサブクラスに任せることである。
そのため、システムのフレームワークを構築するための手段としてよく活用される。
と記載されてます。
今回のサンプルは現在の日付とそれぞれ30日後、60日後の日付を表示させ、ついでにつまらないメッセージも表示させるだけです。
それでは Lambda を使わないプログラムです。(Java8 の新機能の Date and Time API は使ってます。)
package jp.yucchi.oldtemplatemethodpattern;
import java.time.LocalDate;
abstract class DateCalc {
void getNowDate() {
System.out.println("今日は " + LocalDate.now() + " です。");
}
protected abstract void getTargetDate();
void saySorry() {
System.out.println("ワイルドだろぅ ごめんね。こんなサンプルで (ノД`)\n");
}
}
package jp.yucchi.oldtemplatemethodpattern;
import java.time.LocalDate;
class DateCalcImpl_1 extends DateCalc {
@Override
protected void getTargetDate() {
System.out.println("30日後は" + LocalDate.now().plusDays(30) + " です。");
}
}
package jp.yucchi.oldtemplatemethodpattern;
import java.time.LocalDate;
class DateCalcImpl_2 extends DateCalc {
@Override
protected void getTargetDate() {
System.out.println("60日後は" + LocalDate.now().plusDays(60) + " です。");
}
}
package jp.yucchi.oldtemplatemethodpattern;
public class OldTemplateMethodPattern {
public static void main(String[] args) {
printTargetDate(new DateCalcImpl_1());
printTargetDate(new DateCalcImpl_2());
}
private static void printTargetDate(DateCalcImpl_1 dateCalcImpl_1) {
dateCalcImpl_1.getNowDate();
dateCalcImpl_1.getTargetDate();
dateCalcImpl_1.saySorry();
}
private static void printTargetDate(DateCalcImpl_2 dateCalcImpl_2) {
dateCalcImpl_2.getNowDate();
dateCalcImpl_2.getTargetDate();
dateCalcImpl_2.saySorry();
}
}
実行結果は次のようになります。
今日は 2013-04-30 です。
30日後は2013-05-30 です。
ワイルドだろぅ ごめんね。こんなサンプルで (ノД`)
今日は 2013-04-30 です。
60日後は2013-06-29 です。
ワイルドだろぅ ごめんね。こんなサンプルで (ノД`)
当然の結果で何も問題ないですね。
実際にはこのような実装は無いかと思いますが一応 Template Method Pattern の定義に沿っているのでよしとしてください。
それではこのコードを Java8 の Lambda を使うとどうなるか?
こんなになりました~! (*^o^*)
package jp.yucchi.templatemethodpattern4lambda;
import java.time.LocalDate;
@FunctionalInterface
public interface DateInterface {
default void getNowDate() {
System.out.println("今日は " + LocalDate.now() + " です。");
}
void getTargetDate();
default void saySorry() {
System.out.println("ワイルドだろぅ ごめんね。こんなサンプルで (ノД`)\n");
}
}
package jp.yucchi.templatemethodpattern4lambda;
import java.time.LocalDate;
public class TemplateMethodPattern4Lambda {
public static void main(String[] args) {
printTargetDate(() -> System.out.println("30日後は" + LocalDate.now().plusDays(30) + " です。"));
printTargetDate(() -> System.out.println("60日後は" + LocalDate.now().plusDays(60) + " です。"));
}
private static void printTargetDate(DateInterface dateInterface) {
dateInterface.getNowDate();
dateInterface.getTargetDate();
dateInterface.saySorry();
}
}
実行結果は次のようになります。
今日は 2013-04-30 です。
30日後は2013-05-30 です。
ワイルドだろぅ ごめんね。こんなサンプルで (ノД`)
今日は 2013-04-30 です。
60日後は2013-06-29 です。
ワイルドだろぅ ごめんね。こんなサンプルで (ノД`)
こちらも当然の結果で何も問題ないですね。
Lambda を使うと本当にシンプルになります。
「抽象クラスを使ってないじゃないか!」って怒らないでね。(^_^;)
DateInterface (FunctionalInterface) での Default Methods が使えるのが良いですね。
これって Java で禁じ手の多重継承を可能にするような掟破りの裏技のような気がします。
なかなか面白いですね。(^_^)
それでは、お約束の時間です。
この「もっと Lambda 」シリーズは、インターネット上で得た情報を元にそれを少し変更しているだけです。
悲しいことにその情報源は英語なので詳しい内容はわかりません。
よって私の推測で解釈された内容となってますので間違いがあると思います。
Java8 もまだ build86 を使用していますので API の変更により記述方法が変わるかもしれません。
早く正式リリースされて日本語でこの超便利で素敵な新機能を勉強したい今日この頃です。
