Skip to content

Instantly share code, notes, and snippets.

@gakuzzzz
Last active December 11, 2015 22:39
Show Gist options
  • Save gakuzzzz/4671080 to your computer and use it in GitHub Desktop.
Save gakuzzzz/4671080 to your computer and use it in GitHub Desktop.
Doma の Iteration Callback がこんなインターフェイスだったら嬉しい
public interface AccumulableIterationCallback<ACCUM, RECORD> {
ACCUM initialValue();
ACCUM iterate(ACCUM accumulator, RECORD record, IterationContext context);
}
@Dao
public interface EmployeeDao {
<T> T iterateByName(String name, AccumulableIterationCallback<T, ? super Employee> callback);
}
public class EmployeeService {
@Inject
private EmployeeDao employeeDao;
public Integer sumSalary(String name) {
return employeeDao.iterateByName(name, new AccumulableIterationCallback<Integer, Employee>() {
@Override
public Integer initialValue() {
return 0;
}
@Override
public Integer iterate(Integer accumulator, Employee record, IterationContext context) {
return accumulator + record.salary;
}
});
}
public ImmutableMultimap<EmployeeId, Employee> findByNameAndBuildMap(String name) {
return employeeDao.iterateByName(name, new AccumulableIterationCallback<Builder<EmployeeId, Employee>, Employee>() {
@Override
public Builder<EmployeeId, Employee> initialValue() {
return ImmutableMultimap.builder();
}
@Override
public Builder<EmployeeId, Employee> iterate(Builder<EmployeeId, Employee> accumulator, Employee record, IterationContext context) {
return accumulator.put(record.id, record);
}
}).build();
}
}
// 現状のIterationCallback だとこうなる
public class EmployeeService {
@Inject
private EmployeeDao employeeDao;
public Integer sumSalary(String name) {
Integer accumulator = 0;
employeeDao.iterateByName(name, new IterationCallback<Integer, Employee>() {
@Override
public Integer iterate(Employee record, IterationContext context) {
accumulator += record.salary; // 破壊的代入
return accumulator;
}
});
// 検索結果が0件だとやっぱりnullが返ってくるので iterateByName の戻り値は直接使えない。
// どうせ使えないなら Void にすればいいが、そうすると以下の様に全く無駄な return null; を書く必要が出てくる。
return accumulator;
}
public ImmutableMultimap<EmployeeId, Employee> findByNameAndBuildMap(String name) {
final Builder<EmployeeId, Employee> builder = ImmutableMultimap.builder();
employeeDao.iterateByName(name, new IterationCallback<Void, Employee>() {
@Override
public Void iterate(Employee record, IterationContext context) {
builder.put(record.id, record);
return null; // 無意味
}
});
return builder.build();
}
// つまり現状だと IterationCallBack の第一型引数を Void 以外にしてもまともに使えない。
// であれば毎回 <Void, ... とか return null; とか書く必要が無いように IterationCallBack は
// void iterate(T target, IterationContext context);
// の方が便利。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment