Java 8 を使用している場合、ラムダを使用して、検証用の非常にエレガントで読みやすいソリューションを作成できます。
public class Assert {
public interface CheckArgument<O> {
boolean test(O object);
}
public static final <O> O that(O argument, CheckArgument<O> check) {
if (!check.test(argument))
throw new IllegalArgumentException("Illegal argument: " + argument);
return argument;
}
}
次のように使用します。
public void setValue(int value) {
this.value = Assert.that(value, arg -> arg >= 0);
}
例外は次のようになります。
Exception in thread "main" java.lang.IllegalArgumentException: Illegal argument: -7
at com.xyz.util.Assert.that(Assert.java:13)
at com.xyz.Main.main(Main.java:16)
最初の良い点は、上記の Assert クラスだけで本当に必要なものがすべて揃っていることです。
public void setValue(String value) {
this.value = Assert.that(value, arg -> arg != null && !arg.trim().isEmpty());
}
public void setValue(SomeObject value) {
this.value = Assert.that(value, arg -> arg != null && arg.someTest());
}
もちろんthat()
、さまざまな方法で実装できます。フォーマット文字列と引数を使用して、他の種類の例外をスローするなどです。
ただし、さまざまなテストを実行するために実装する必要はありません。
次のような場合は、事前にパッケージ テストを実行できないわけではありません。
public static CheckArgument<Object> isNotNull = arg -> arg != null;
Assert.that(x, Assert.isNotNull);
// with a static import:
Assert.that(x, isNotNull);
これがパフォーマンスに悪いのか、他の理由で良い考えでないのか、私にはわかりません。(自分でラムダを調べ始めたところですが、コードは正常に動作しているようです...)しかし、それをAssert
短く保つことができ(プロジェクトにとって重要ではない可能性のある依存関係は必要ありません)、テストが非常に見やすいことが気に入っています。
エラーメッセージを改善する方法は次のとおりです。
public static final <O> O that(O argument, CheckArgument<O> check,
String format, Object... objects)
{
if (!check.test(argument))
throw new IllegalArgumentException(
String.format(format, objects));
return argument;
}
あなたはそれを次のように呼びます:
public void setValue(String value) {
this.value = Assert.that(value,
arg -> arg != null && arg.trim().isEmpty(),
"String value is empty or null: %s", value);
}
そして出てくる:
Exception in thread "main" java.lang.IllegalArgumentException: String value is empty or null: null
at com.xyz.util.Assert.that(Assert.java:21)
at com.xyz.Main.main(Main.java:16)
更新:パッケージ化されたテストで構造を使用する場合x = Assert...
、結果はパッケージ化されたテストで使用される型にキャストされます。したがって、変数の型にキャストし直す必要があります...SomeClass x = (SomeClass) Assert.that(x, isNotNull)