Junichi Kato
j5ik2****@gmail*****
2008年 6月 8日 (日) 22:31:08 JST
かとうです. MIYAMOTO Daisuke さんは書きました: > 都元でっす。 > > ぱっと見てみたんですが、このS2のforEachメソッドは、第4案とは違う考え方なんでしょうか〜。 > 根本的な違いはあんまり感じなかったんですが。。。 > あそうですね.第4案のグループに入るとは思います. for(ColumnModel column : table.getColumns()) { // 前処理 System.out.println(column.getName()); // 後処理 } 実際ループで処理すべきことは,ここでは System.out.println(column.getName()); だけなんだけど,実際にはそうもいかず,要素を取り出したときと,要素を処理したときの後処理などが入ってくるので できるだけ,ループの処理もオブジェクト化して,AOP的なアプローチがすぐにとれるようにしてます. 以下のような感じです.基本的には案4 (Iterable型)として,utilパッケージにTraversalがあると便利だと思いますが. Traversal.forEachColumn(table, new Traversal.ColumnHandler(){ public Object processColumn(Column column) { // Columnをお気に召すまま return null; } }); public class Traversal { public static interface ColumnHandler { Object processColumn(Column column); } public Object forEachColumn(Table table, ColumnHandler handler) { for(Column column : table.getColumns()){ // 前処理 Object result = handler.processColumn(column.clone()); // 後処理 if (result != null){ return result; } } return null; } } > 2008/06/08 18:55 Junichi Kato <j5ik2****@gmail*****>: > >> 加藤です。 >> >> 断片的ですみませんが、forEach話だけに反応しますw >> >> http://s2container.seasar.org/2.4/s2-framework/ja/apidocs/org/seasar/framework/container/util/Traversal.html#forEachContainer(org.seasar.framework.container.S2Container,%20org.seasar.framework.container.util.Traversal.S2ContainerHandler) >> >> このあたりのインターフェイスを見習ったらどうかと思うのですが、 >> >> forEachComponentメソッドなんぞはS2コンテナ内部で管理しているコンポーネン >> トをforEachで検索するためのインターフェイスです。 >> forEachのループ部分は、インターフェイスを指定してやれば自由に定義できま >> す。私の場合はその場で無名クラスを実装して解決してしまいます。 >> 非常に楽ちんですし、forEachで渡す要素をcloneしてから渡せば、もとのコレク >> ションを破壊することもできませんし、またコレクションの更新が >> 必要なら、コレクション自身を渡すのではなく、ここでいう無名クラスにそのた >> めのコンテキストを渡してあげて更新できるようにすればよいと >> 思います。 >> >> 以上! >> >> >> MIYAMOTO Daisuke さんは書きました: >> >>> 都元です。 >>> >>> コミットはまだしていませんが、一足先に、最低限必要なメソッドの実装を始めています。 >>> >>> そこで迷っているのですが、Collection系のフィールドのaccessorメソッド(特にgetter)です。 >>> 例えば、TableModelにはList<ColumnModel> columnsフィールドがあります。 >>> このフィールドの直接のgetterを用意するのは、実装を公にし過ぎなんですよね。 >>> >>> 地豆会でも指摘があった通り、TableModel#addColumn(column) では、変更を捕捉して >>> ChangeEventを飛ばす訳ですが、万一 getColumns().add(column) されてしまった場合、 >>> 変更を検知することができません。 >>> >>> というわけで、カラムの追加という観点では、columnsのgetterは使わず、addColumn >>> メソッドを用意する、ということになると思います。 >>> >>> 次に、暫くすると「テーブルが持つカラムをforで回したい」という状況が頻繁に訪れます。 >>> 従来ですと、これを実現する為に、getColumns() を用意し、 >>> >>> >>> >>>>>> 案1 (従来型) >>>>>> >>>>>> >>> ---- TableModel >>> public List<ColumnModel> getColumns() { >>> return columns; >>> } >>> ---- client >>> for(ColumnModel column : table.getColumns()) { >>> System.out.println(column.getName()); >>> } >>> <<< >>> >>> というコードを書いていました。しかし、これが必要だからといってgetColumnsを用意して >>> しまうと、先の「getColumns().add(column)」を回避することができません。 >>> bacchusでは「回避できないので、とりあえずやらないように気をつける」という >>> 対処を行って来ましたが、なんとかしたいもんです。 >>> >>> 現在俺の頭にあるのは「columnsのイテレータを返すメソッドを作る」という手段と、 >>> 前どこかで話が出た「forEachメソッドを作る」という手段です。 >>> >>> >>> >>>>>> 案2 (Iterator型) >>>>>> >>>>>> >>> ---- TableModel >>> public Iterator<ColumnModel> getColumnIterator() { >>> return columns.iterator(); >>> } >>> ---- client >>> Iterator<ColumnModel> itr = deptTable.getColumnIterator(); >>> while(itr.hasNext()) { >>> ColumnModel column = itr.next(); >>> System.out.println(column.getName()); >>> } >>> <<< >>> >>> >>> >>>>>> 案3 (ForEachHandler型) >>>>>> >>>>>> >>> ---- >>> public interface ForEachHandler<T> { >>> void handle(T model); >>> } >>> ---- TableModel >>> public void forEach(ForEachHandler<ColumnModel> handler) { >>> for (ColumnModel column : columns) { >>> handler.handle(column); >>> } >>> } >>> ---- client >>> deptTable.forEach(new ForEachHandler<ColumnModel>() { >>> public void handle(ColumnModel column) { >>> System.out.println(column.getName()); >>> } >>> }); >>> <<< >>> >>> >>> しかし前者に関しては「なんかイテレータって前時代的じゃね?@@:」という >>> イメージがあったりします。もしかしたら、この意識間違ってる?(汗 >>> >>> で、後者に関しては「キモくないですか? 大丈夫ですか?w」という危惧があります。 >>> 安全性を確保できても、見通しが悪くなってしまうのでは採用の価値低いですからねぇ。。。 >>> >>> この辺り、意見をまとめたいと思いますので、コメント下さい。 >>> >>> と、ここまで書いて、良いアイデアが思いついた気がします。 >>> getColumnsでList<ColumnModel>を返すからいけないんだ。 >>> >>> >>> >>>>>> 案4 (Iterable型) >>>>>> >>>>>> >>> ---- TableModel >>> public Iterable<ColumnModel> getColumns() { >>> return columns; >>> } >>> ---- client >>> for(ColumnModel column : table.getColumns()) { >>> System.out.println(column.getName()); >>> } >>> <<< >>> >>> これならば、iterableにはadd出来ないので安全、かつ、見通しの良いforが書ける! >>> なんか結論出ちゃった気がしますがw みんなが見れば案4はキモいかもしれないw >>> ということで、一応ご意見ぼしゅー。 >>> >>> >>> >> _______________________________________________ >> Jiemamy-dev mailing list >> Jiema****@lists***** >> http://lists.sourceforge.jp/mailman/listinfo/jiemamy-dev >> >> > > > >