Interfaceに内部enumをつけて、そのenumが他のinterfaceを実装していて、自己満足なコードができている。
と、ツイートしたので、その自己満足なコードを晒してみる。
package orz.mikeneck.gae.slim3.model.alarm;
import java.util.Date;
import java.util.TimeZone;
import org.slim3.controller.validator.Validator;
import org.slim3.controller.validator.Validators;
import orz.mikeneck.gae.slim3.util.AttributeKeyValue;
import orz.mikeneck.gae.slim3.util.AttributeValidation;
public interface AlarmDate {
public static final TimeZone TIME_ZONE = TimeZone.getTimeZone("Asia/Tokyo");
public static final String KEY_YEAR = "YEAR";
public static final String KEY_MONTH = "MONTH";
public static final String KEY_DATE = "DATE";
public static final String KEY_HOUR = "HOUR_OF_DAY";
public static final String KEY_MINUTE = "MINUTE";
public static final long MONTH_MAX = 12;
public static final long MONTH_MIN = 1;
public static final long DATE_MAX = 31;
public static final long DATE_MIN = 1;
public static final long HOUR_MAX = 23;
public static final long HOUR_MIN = 0;
public static final long MINUTE_MIN = 0;
public static final long MINUTE_MAX = 55;
public int year();
public int month();
public int date();
public int hour();
public int minute();
public Date getCreatedAt();
enum AttributeMapper implements AttributeKeyValue<AlarmDate>, AttributeValidation {
ATTRIBUTE_YEAR {
@Override
public String key() {
return KEY_YEAR;
}
@Override
public <T> T value(AlarmDate model, Class<T> klass) {
return klass.cast(model.year());
}
@Override
public Class<?> type() {
return Integer.class;
}
@Override
public Validator[] validation(Validators valid) {
return new Validator[] {
valid.required(),
valid.integerType()};
}
}, ATTRIBUTE_MONTH {
@Override
public String key() {
return KEY_MONTH;
}
@Override
public <T> T value(AlarmDate model, Class<T> klass) {
return klass.cast(model.month());
}
@Override
public Class<?> type() {
return Integer.class;
}
@Override
public Validator[] validation(Validators valid) {
return new Validator[] {
valid.required(),
valid.integerType(),
valid.longRange(MONTH_MIN, MONTH_MAX)};
}
}, ATTRIBUTE_DATE {
@Override
public String key() {
return KEY_DATE;
}
@Override
public <T> T value(AlarmDate model, Class<T> klass) {
return klass.cast(model.date());
}
@Override
public Class<?> type() {
return Integer.class;
}
@Override
public Validator[] validation(Validators valid) {
return new Validator[] {
valid.required(),
valid.integerType(),
valid.longRange(DATE_MIN, DATE_MAX)};
}
}, ATTRIBUTE_HOUR_OF_DAY {
@Override
public String key() {
return KEY_HOUR;
}
@Override
public <T> T value(AlarmDate model, Class<T> klass) {
return klass.cast(model.hour());
}
@Override
public Class<?> type() {
return Integer.class;
}
@Override
public Validator[] validation(Validators valid) {
return new Validator[] {
valid.required(),
valid.integerType(),
valid.longRange(HOUR_MIN, HOUR_MAX)
};
}
}, ATTRIBUTE_MINUTE {
@Override
public String key() {
return KEY_MINUTE;
}
@Override
public <T> T value(AlarmDate model, Class<T> klass) {
return klass.cast(model.minute());
}
@Override
public Class<?> type() {
return Integer.class;
}
@Override
public Validator[] validation(Validators valid) {
return new Validator[] {
valid.required(),
valid.integerType(),
valid.longRange(MINUTE_MIN, MINUTE_MAX)
};
}
};
@Override
abstract public String key();
@Override
abstract public <T> T value(AlarmDate model, Class<T> klass);
@Override
abstract public Class<?> type();
@Override
abstract public Validator[] validation(Validators valid);
@Override
public void validate(Validators valid) {
valid.add(key(), validation(valid));
}
}
}
こやつは、Slim3のModelクラスのインターフェースなのですが、何がいいかというと、
request
のマッピングとか、Validationのコードなどが劇的にキレイになる。Mapping
package orz.mikeneck.gae.slim3.controller.alarm;
import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;
import orz.mikeneck.gae.slim3.model.alarm.AlarmDate;
import orz.mikeneck.gae.slim3.model.alarm.AlarmDateModel;
public class IndexController extends Controller {
@Override
public Navigation run() throws Exception {
AlarmDate model = new AlarmDateModel();
for(AlarmDate.AttributeMapper mapper : AlarmDate.AttributeMapper.values())
request.setAttribute(mapper.key(), mapper.value(model, mapper.type()));
return forward("index.jsp");
}
}
Validators
package orz.mikeneck.gae.slim3.controller.alarm;
import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;
import org.slim3.controller.validator.Validators;
import orz.mikeneck.gae.slim3.model.alarm.AlarmDate;
public class WakeController extends Controller {
@Override
public Navigation run() throws Exception {
Validators valid = new Validators(request);
for(AlarmDate.AttributeMapper mapper : AlarmDate.AttributeMapper.values())
mapper.validate(valid);
return redirect(basePath);
}
}
Validationとかの部分が二行で書けるので、コントローラーにモデルに関する複雑なことを書かんでよくなる。
まあ、もっといいやりかたがあるんだろうけど、コレが今のオレの程度…orz
0 件のコメント:
コメントを投稿