Java 8 Lambda関数プログラミング入門(五)

4352 ワード

テスト、デバッグ、再構築
再構築、テスト駆動開発(TDD)、持続的統合(CI)がますます流行しており、Lambda式を日常的なプログラミング作業に適用する必要がある場合は、ユニットテストの作成方法を学ばなければなりません.この章では,Lambda式を用いて非集合クラスコードの品質を向上させる方法を見る.
再構築候補(Lambda Refactoring Candidates)
次のポイントは、Lambda化(lambdafication)がいつ自分のアプリケーションまたはクラスライブラリを構築すべきかを決定するのに役立ちます.それぞれは、Lambda化によって修復することができる局所的な逆モードまたはコード異臭と見なすことができる.
出入り、ふらふら(In,Out,In,Out,Shake It All About)
プログラムにログを記録します.例:
Logger logger = new Logger(); 
if (logger.isDebugEnabled()) {
     logger.debug("Look at this: " + expensiveOperation());
}

このコードは、まずisDebugEnabledメソッドを呼び出してブール値を抽出し、デバッグレベルが有効であるかどうかを確認し、有効である場合、Loggerオブジェクトの対応するメソッドレコードログを呼び出す.自分のコードがオブジェクトを絶えずクエリーし、操作していることに気づいたら、最後にオブジェクトに値を設定することを目的としている場合は、このコードはあなたが操作しているオブジェクトに属するはずです.
この逆モードは,コードすなわちデータを伝達することによって容易に解決できる.オブジェクトの値をクエリーして設定するよりも、計算された値に従って適切な動作を実行するLambda式を入力します.プログラムがデバッグレベルにあり、Lambda式を使用する論理がLoggerオブジェクトにカプセル化されているかどうかを確認すると、Lambda式が呼び出されます.例:
Logger logger = new Logger();
logger.debug(() -> "Look at this: " + expensiveOperation());

上記のログの例は、Lambda式を使用してオブジェクト向けプログラミング(OOP)をよりよく行う方法も示しており、オブジェクト向けプログラミングの核心の一つは、ログのレベルなどのローカル状態をカプセル化することである.通常、この点はうまくいかず、isDebugEnabled法は内部状態を暴露した.Lambda式を使用する場合、外部のコードはログレベルをチェックする必要はありません.
孤独のカバー(The Lonely Override)
このコードの異臭は継承を使用し,その目的はただ一つの方法を上書きするためである.例:
ThreadLocal thisAlbum = new ThreadLocal () { 
    @Override 
    protected Album initialValue() {
        return database.lookupCurrentAlbum(); 
    }
};

Java 8では、ファクトリメソッドwithInitialにSupplierオブジェクトのインスタンスを入力してオブジェクトを作成できます.例:
ThreadLocal thisAlbum
    = ThreadLocal.withInitial(() -> database.lookupCurrentAlbum());

2番目の例が1番目より優れている理由:
  • 既存のSupplierインスタンスは、再カプセル化する必要がなく、ここで使用することができ、再利用と組合せを奨励する.
  • コードはより明確です.
  • JVMはクラスを1つ少なくロードします.

  • 同じものを2回書く(Behavioral Write Everything Twice)
    あなたの労働(Don't Repeat Yourself,DRY)を繰り返さないのはよく知られているパターンで、その反対側は同じものを2回書く(Write Everything Twice,WET).
    すべてのWETの場合がLambda化に適しているわけではありません.場合によっては、繰り返しは、システムの過度な結合を回避する唯一の方法である.WETのコードLambdaをいつ化すればいいですか?ここには参考になる信号があります.全体的にほぼ似たパターンがあり、動作が異なるだけであれば、Lambda式を加えてみましょう.
    Lambda式のセルテスト
    ユニットテストは、コードの動作が予想される方法に合致するかどうかをテストします.
    Lambda式はユニットテストにいくつかの面倒をもたらし、Lambda式には名前がなく、テストコードで直接呼び出すことができません.
    テストコードにLambda式をコピーしてテストすることができますが、この方法の副作用はテストが本当の実装ではありません.実装コードを変更したとしても、テストは通過し、実装はすでに別のことをしている可能性があります.
    この問題を解決するには2つの方法がある.1つ目は、Lambda式自体ではなく、その方法を測定する方法のテストにLambda式を入れます.2つ目はメソッドリファレンスで、どのLambda式も通常のメソッドに書き換えられ、メソッドリファレンスを使用して直接リファレンスされます.
    身代わりをテストするときにLambda式を使用する
    ユニットテストを記述する一般的な方法の1つは、システム内の他のモジュールの所望の挙動をテスト代替を用いて記述することである.この方法は役に立ちます.ユニットテストは他のモジュールから離れてクラスや方法をテストすることができ、テストの代わりにユニットテストでこの隔離を実現することができます.
    【テストアバタはシミュレーションとも呼ばれますが、実際にテストスタブとシミュレーションはテストアバタに属します.違いは、シミュレーションがコードを検証できる行為です.Javaで使用されているMokitoPowerMokitoなどです.
    不活性評価とデバッグ
    デバッグ時に通常、ブレークポイント、単一ステップトレースプログラムの各ステップが設定されます.ストリームを使用すると、反復がクラスライブラリによって制御され、多くのストリーム操作が不活性に評価されるため、デバッグがより複雑になる可能性があります.
    ログと印刷メッセージ
    コレクションで大量の操作を行うと仮定し、コードをデバッグし、各ステップの操作の結果を見たいとします.各ステップでセット内の値を印刷することができます.これは、いくつかの中間ステップが不活性に評価されるため、ストリームでは難しいです.
    ソリューション:peak
    幸いなことに、ストリームには各値を表示しながらストリームを操作する方法があります.これがpeekの方法です.peekは、繰り返しのストリーム動作を回避しながら、ストリーム内の値を出力することができる.peekの方法を使用すると、出力は、log4jjava.util.logging、またはslf4jのような既存のログシステムにも指向される.
    ストリームの中間にブレークポイントを設定する
    ログを記録するこれはpeekメソッドの用途の1つです.デバッグサイクルのように一歩一歩追跡するために、peekメソッドにブレークポイントを追加すると、ストリーム内の要素を1つずつデバッグできます.
    参考資料:Java 8関数式プログラミング著者:(英)ウォーバートン著備考:転載出典を明記してください:http://blog.csdn.net/wsyw126/article/details/52765629 作者:WSYW 126