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

Back to archive index

Junichi Kato j5ik2****@gmail*****
2008年 6月 8日 (日) 23:46:14 JST


加藤です.

お疲れ様です.

まず,設計のポリシーとして,
クライアント側に自由度を与えるのか,与えないのか?
だとおもっていて,

table.getColumns().add(xxx) はだめで
table.addColumn(xxx)にするという隠ぺい方針なんですが,

table.getColumns()でforさせるというのは,逆にオープンになっているように
思えるんですよね.


値の参照系は,forやキーによる値の取得などの処理が考えられると思います
が,そのようなコードブロックを毎回クライアント側でしこしこ書くのは面倒だ
なぁと.
面倒ならUtilityクラスに今回のようなforで検索するメソッド系をまとめると思
うので,それなら最初からforEachでいいかと思うんですよね.

なので,

table.addColumn(xxx);
table.removeColumn(xxx);
table.getColumn(columnKey);
table.forEachColumns(new ColumnHandler(){ });

のほうが統一感あるなぁと.




> ところで 案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
>> ということで、一応ご意見ぼしゅー。
>>     
>
>   




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