共通処理とラムダ式
近況
4月から某SI系企業に就職。 3ヶ月間の研修が終わり、7月から配属。
で、OJT…なんだけど次のプロジェクトが始まらないので、 前のプロジェクトのソース読んだり雑用したりしてる。
闇のソースリーディング
で、サーバサイドWebアプリのソースを勉強するという名目で JavaとかJavaScriptとかテキトーに読む日が続いてるんだけど、 まあ重複コードの多いこと。
例えばコントローラの各アクションで共通する処理 (認証情報の確認、チェックボックスの値のセット、等々)が ぜんぶベタ書きされてる。
流石にウンザリしたので、プロジェクトをコピーしてローカルで実行環境作って ソースをいじり回すことにした。
共通処理の抜き出し
匿名クラス
個別処理が関数として渡せるとすれば、 共通処理を行うメソッドはこんな感じに書きたい。
プロジェクトではPlay Framework使ってるのでそれっぽく。
private Result commonAction(/* 個別処理の関数 */func) { commonAction1(); func(); commonAction2(); return ok(); }
ただJavaは関数が第一級オブジェクトじゃないので、 やるならクラス作って渡す必要がある。 匿名クラス使って個別処理も書くとこんな感じ。
private interface Func { void func(Object someArg); } private Result commonAction(Func func) { commonAction1(); func.func(someArg); commonAction2(); return ok(); } public Result individualAction() { Func func = new Func() { public void func(Object someArg) { someOperation(someArg); }; }; return this.commonAction(func); }
ラムダ式
で、ここまで書いて思い当たる。 何かこのインターフェース見たことあるなと。
あ、これConsumerじゃん。 関数型インターフェースじゃん。
じゃあラムダ式使って書き直しましょ。
private Result commonAction(Consumer<Object> consumer) { commonAction1(); consumer.accept(someArg); commonAction2(); return ok(); } public Result individualAction() { return this.commonAction(someArg -> someOperation(someArg)); }