Sample というオブジェクトが存在し Date型の属性値を必ず持ってるとします。
これを、オブジェクトの自然ソートでなくて、オブジェクトの属性値に
よるソートして使用したい時に、今までは、、、
public class SampleSetWrapper{
private Set<Sample> sampleSet;
public DataSet(){
this.sampleSet = new TreeSet<Sample>(Comparatorのインスタンス);
// Comparator 実装クラスは、インナークラスなどに書いたりしていた。
}
// this.sampleSet への追加メソッド、参照メソッドを用意しなければならなかった。
}
:
SampleSetWrapper set = new SampleSetWrapper();
:
の様に使用していた。
ラッパーをコーディングする時に、Comparator 実装クラスを書くのは仕方ないとして
フィールドに抱える Collection のアクセスメソッドを用意(橋渡し)しないと
ならなくて面倒であったのと、ラッパーのメソッドに依存してしまった。
面倒くさいのはともかく、依存性は良くない!
→ 今まで、いつもすっきりしないダメなコードだと感じていた。
Google guice 2.0 の Provides を使用してみる。
public final class SampleTreeSetFactory{
private SampleTreeSetFactory(){}
public static TreeSet<Sample> create(){
Injector injector = Guice.createInjector(new AbstractModule(){
@Override
protected void configure(){}
// 日付、昇順コンパレータ を Provides
@SuppressWarnings("unused")
@Provides
Comparator<Sample> ascDateProvides(){
return new Comparator<Sample>(){
@Override
public int compare(Sample p1,Sample p2){
return p1.getDate().compareTo(p2.getDate()) >= 0 ? 1 : -1;
}
};
}
}
);
return injector.getInstance(SampleTreeSet.class);
}
}
=======================================
import java.util.Comparator;
import java.util.TreeSet;
import com.google.inject.Inject;
class SampleTreeSet extends TreeSet<Sample>{
@Inject
protected SampleTreeSet(Comparator<Sample> c){
super(c);
}
}
=======================================
Set<Sample> fooset = SampleTreeSetFactory.create();
で、日付昇順に並ぶ Set を作成し、
java.util.Set の add 、iterator 、size といったメソッドを直接使用します。
@Provides が付くメソッド内容、Comparator 実装の生成を変更するだけで
ソート方法を調整します。
Wrapper のように コレクションメソッドを新たに作ってないので、
java.util.Set のメソッドを使うことになり少しだけ良いスタイルである。
本当はもっと汎用性のある書き方があるのだが。。。
本当は、injector.getInstance で指定するインジェクト対象である TreeSet 継承クラスは、
インナークラスで書きたかったのだが、
Google guice の リリース内容を説明してるページ に、
はっきりと、
インナークラスへのインジェクトで non-static を対応するつもりがないと書いてある。