[Jiemamy-dev:45] Re: [RFC] Collectionのアクセサメソッドについて

Back to archive index

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




Jiemamy-dev メーリングリストの案内
Back to archive index