NAGAYASU Yukinobu
nagay****@yukin*****
2008年 6月 8日 (日) 23:23:52 JST
ゆきのぶです。 一通り読んで理解したつもりのところで、案4が一番かなと思いました。 > >>> 案1 (従来型) イベントが飛ばない場合があるので、これは使いたくない点、同感でつ。 > >>> 案2 (Iterator型) C++ で std::vector とかをたくさん使った私には、かなり自然な感じに 見えます。前時代的って感じは特にしないなぁ、、、もしや私遅れてる? > >>> 案3 (ForEachHandler型) これはキモいっす。Perl で似たようなことをやったんですが、自分でやっ てて気持ち悪さが拭えませんでしたよ、えぇ orz > >>> 案4 (Iterable型) 案2 の進化系という感じがして素敵に見えます。クライアント側のコード が 案2 よりもすっきりして良いですね。 ところで 案2 か 案4 の場合についてなんですが、Iterable から返す Iterator には remove() メソッドがあるんですけど、これの実装ってど うしましょうね。 インタフェース Iterable<T> http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/lang/Iterable.html インタフェース Iterator<E> http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/util/Iterator.html ゆきのぶとしては、今回の目的(for したい)を考えるとあまり必要とい う感じもしないので、実装せずに UnsupportedOperationException を返 すのが良いんじゃないかと思いました。 > 都元です。 > > コミットはまだしていませんが、一足先に、最低限必要なメソッドの実装を始めています。 > > そこで迷っているのですが、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 > ということで、一応ご意見ぼしゅー。 -- 永安 佑希允 (ながやす ゆきのぶ) <nagay****@yukin*****> Blog: http://www.yukinobu.jp/tdiary/ Twitter: http://twitter.com/yukinobu