- - PR -
ArrayList removeRangeの使い方
| 投稿者 | 投稿内容 | ||||||||
|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2003-06-05 13:01
割り込んですみません
yamasaさんではないのですが ArrayListをListとして定義していた方が後の変更が容易だからではないでしょうか 少なくともデザインパターンなどの情報によると、インタフェースに対してプログラミングするのであって、実装に対してプログラムするのではない。 などと紹介されています。 List list = new ArrayList(); この場合だとListインターフェースの既知の実装クラスへの変更が簡単に行えるという ことだと自分では思っているのですが... 実際のとこどうなんでしょう | ||||||||
|
投稿日時: 2003-06-05 14:28
こんにちわ。 わたしもArrayListを使用する時上記のようなことを意識する ことはあまりなかったんですが、以下のようなケースではどうでしょうか? ArrayListよりこういうケースの方がイメージしやすいのかな、と思いました。 アナタは他サーバとの通信インタフェース部分のクラスを作らなければなりません。 しかし、以下の条件が出ています。 最初の2ヶ月はソケット通信なんだが その後RMIによる通信に変わる可能性がある #他サーバ側の変更の可能性があるということ。 #こちらは他サーバのインタフェースに合わせなければなりません そして変更の際は、なるべく改造なしで簡単に変更できる仕組みにしたい。 この場合、僕はソケット用とRMI用の通信部分に特化したクラスを作ります。 ・ソケット用:SocketAdapter.java ・RMI用:RMIAdapter.java そしてそれら二つの親クラスとしてAdapter.javaを作ります。 Adapter.javaにはexecute()とか適当な通信用メソッドを作ります。 ソケット・RMI用クラスはこのexecute()をオーバーライドします。 そんで、まずはAdapterの設定として 適当なFactoryクラスを作ってソケット・RMI用を格納しておきます。 Adapter socket = new SocketAdapter(); Adapter rmi = new RMIAdapter(); add(socket); add(rmi); そんで、使う側ですが Adapter adapter = Factory.get("hoge"); でAdapterクラスを取得します。 #hogeは設定ファイルか何かでソケット・RMIを識別できる識別子 #もちろんFactoryにはこの識別子で登録 最後に、adapter.execute(); この方法で何がうれしいかというと、クライアント側(使う側)が 取得しているクラスはAdapterです。 しかし、実際使用しているクラスはSocketAdapterもしくはRMIAdapterです。 つまりクライアント側から何を通信として使用しているのかを隠蔽できるのです。 上の例で行くと、最初の2ヶ月は識別子hogeにはSokcetを使うような 設定にしておけば、 Adapter adapter = Factory.get("hoge"); で取得するAdapterの実態はSocketAdapterになります。 そいで、2ヵ月後からhogeをRMIを使うような設定にすれば Adapter adapter = Factory.get("hoge"); で取得するAdapterの実態はRMIAdapterになります。 ソースコードの修正は全くしなくて良いハズです。 また、全く新しい通信手段が出てきた場合は 新規AdapterクラスHogeAdapterを一個作ってやって Factoryクラスに追加する修正を加えるだけで クライアント側の Adapter adapter = Factory.get("hoge"); というコードは何も変更がないですよね。 Adapter(抽象) SocketAdapter(具象) 抽象化することでの変更容易性とはこんな時に威力を 発揮するのではないでしょうか。 #僕もまだまだ未熟なので、間違い等指摘お願いします。 | ||||||||
|
投稿日時: 2003-06-06 10:11
どうも、Wataです。およびでないかもしれないですが、
簡単な例で行くと、
と定義する場合、Bのほうが断然便利だよね。 AはArrayListしか使えないのに対して、 後者は、VectorやLinkedListやArrays.asList()のリストなど 全てのリストが使えます。 同様に、新しいクラスを定義する場合も共通のインターフェイスなどを 用いれば、そのインターフェイスを実装するクラスを全て同一視することができます。 | ||||||||
|
投稿日時: 2003-06-07 20:02
返信が遅くなってすみません。
すでに多くの方々が回答なさっている通り、 「インタフェースに対してプログラミングする」 というのが考え方の根底にあるわけですね。 良い設計では大抵このようにインターフェースと実装の 分離が行なわれているものです。 最初は難しいかもしれませんが、慣れれば無意識のうちに List list = new ArrayList(); や public void doSomething(List list); という書き方ができるようになりますよ。 | ||||||||
|
投稿日時: 2003-06-09 10:00
こんにちわ。 ちょっと質問させてください。 僕も書いたんですが、あまり上記でいう 『インタフェースに対してプログラミングする』 を常日ごろから意識していませんでした。 それで上記コード例を見て疑問に思ったのですが、 両者とも取得、もしくは引数となるものはListなわけですが ここでArrayList特有のメソッドを使用したい場合はどうするのでしょうか? >public void doSomething(List list); この場合なんか特にそうなのですが メソッド内ではArrayListの、例えばtrimToSize()とか使用する場合は (ArrayList)list とキャストする必要があると思います。 しかし、メソッドの引数がListであり、必ずArrayListが入ってくると は保証されていないですよね? というか、そもそも僕が考えている状況、というか考えは 『そのような状況になる設計自体悪い』んでしょうか? | ||||||||
|
投稿日時: 2003-06-09 12:48
みーちくです。
皆様いろいろ、ご意見ありがとうございます。 私自身、Javaでのプログラム経験はまだ、一年にも満たない初心者です。 私の仕事の大部分は、DBに登録されているデータを表示したり、 更新・削除という作業が大部分です。 ほとんとが、addやgetのみ使用しております。 検索する件数をいちいちカウントを取って、配列で取得するより、 ArrayList等に入れちゃうほうが効率が良いと思って、今までプログラミング してきたのですが・・・。 ですので、ぽちさんと同じく、『インタフェースに対してプログラミングする』 という事を考えておりませんでした。 | ||||||||
|
投稿日時: 2003-06-09 14:19
こういう場合は public void doSomething(List list) if(list instanceof ArrayList){ ArrayList arrayList = (ArrayList)list; arrayList.trimToSize(); } } などとしますが、ほんとは良くないケースですよね! こういうことすると私はよく怒られます、 解決としてはFatoryなどで Listインターフェースを実装しているクラスごとに、 public void doSomething(List list) を持つ実装クラスを生成するというのが、 良いのかなと思っています。 例 UseArrayList class ArrayListを使用するのを知っている UseVector class Vectorを使用するのを知っている 二つあるとしますこのクラスはUseListを継承していて public void doSomething(List list)を実装しているとします。 中身は、ご想像におまかせします。 あるFactoryクラスにてListの型でUseListのを返すようにします public UseList getUseList(List list){ UseList useList= nell; if(list instanceof ArrayList){ return useList = new UseArrayList(): } else if(list instanceof Vector){ return useList = new UseVector } } こんな感じなのですが、あとはデザインパターンの本を読むなり理解していただきたいと おもっています。 長くなってしまいましたが結局は 「自分以外の人はListの実装を知らなくてもいいんですよ!」 ということをいいたかっただけです。 間違いなどありましたらよろしくお願いします。 | ||||||||
|
投稿日時: 2003-06-11 16:48
(株)ぽちさんの書き込み (2003-06-09 10:00) より:
>ここでArrayList特有のメソッドを使用したい場合はどうするのでしょうか? ArrayListが要求されるようなメソッドであれば、ArrayList型で宣言するように しましょう。ArrayList以外のList型も受け取るメソッド内でArrayListに特化した 処理を行うのであれば、ニシトミさんの書き込みにあるような方法を使うしかないですね。 ちなみに「インターフェースに対してプログラミングする」の「インターフェース」は、 Java言語のInterfaceとイコールではありません。 | ||||||||
