アノテーションの使い方は理解してたが、自作したことなかったので、バリデータを自作してみた。
ネーミングだったり細かいエラーなどは省略。
作成して分かったのは
とりあえず作って分かったのは、@interfaceをつぶしの効くものにしないと@interfaceだらけになってしまうこと。
作りながら考えたのは
Validator.java内で各Annotationのバリデーションロジックを書くのではなく、Annotationクラス自体が自分のバリデーションロジックを持たせて、Validator側を少し書き直せばValidatorとAnnotationが互いに意識せず、かつAnnotationだけを追加すればValidatorに追加しなくても動くみたいな疎結合になるかもしれないと思った。
だけど、Annotationはメソッドに制限があったし、以前見かけたValidatorではそんな事してなかったので、きっと別の理由でダメなのだろう。
MainActivity.java
@Override
public void onClick(View v) {
if (v.getId() == R.id.registerButton) {
Weight weight = new Weight(measureEditText.getEditableText().toString(), weightEditText.getEditableText().toString());
ValidateResult result = Validator.validation(weight);
if (result.isOk()) {
Toast.makeText(this, "登録成功", Toast.LENGTH_SHORT).show();
} else {
String msg = result.getMessage();
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
}
}
Validator.java
public class Validator {
public static ValidateResult validation(Object target) {
try {
Class<?> clazz = target.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
NotEmpty notEmpty = field.getAnnotation(NotEmpty.class);
if (notEmpty != null) {
field.setAccessible(true);
Object object = field.get(target);
if (object instanceof String) {
String fieldObject = (String) field.get(target);
if (TextUtils.isEmpty(fieldObject) == true) {
return new ValidateResult(false, notEmpty.value());
}
} else {
Object fieldObject = field.get(target);
if (fieldObject == null) {
return new ValidateResult(false, notEmpty.value());
}
}
}
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return new ValidateResult(true);
}
}
NotEmpty.java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface NotEmpty {
String value();
}
Weight.java
public class Weight {
public Weight(String date, String weight) {
measurementDate = date;
this.weight = weight;
}
@NotEmpty("日付を入力してください")
private final String measurementDate;
@NotEmpty("体重を入力してください")
private final String weight;
}