Если вы используете 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)