ウィリアムのいたずらの、まちあるき、たべあるき

ウィリアムのいたずらが、街歩き、食べ物、音楽等の個人的見解を主に書くブログです(たま~にコンピューター関係も)

デザインパターンの23種類の各パターンは、要するにこうだ!と言い切る(その2:構造関連編)

2006-09-01 11:35:00 | JavaとWeb

 以前に書いた、デザインパターンの話のつづき、今回は、構造に関するものです。

 GoF本では、デザインパターンを主に3つに分けている。
 1つめは、生成に関するもの
 2つめは、構造に関するもの
 3つめは、振る舞いに関するもの

1つめの生成はわかりやすいです。3つめの振る舞いというのも、これはメソッドに関するもんだと思いをめぐらすことができます。。。が、構造っていわれても。。。クラス割り?
 いまいちはっきりしませんが、そうやって割っているので、そういうことにしましょう。




 で、今回は、構造に関するものです。ここに属するものは

・Adapter   いわゆるラッパー
・Bride    機能と実装をわける
・Composite  違うものを1つの上位クラスにいれて、同じように扱う
・Decorator  付け足す
・Facade    入り口を1つにする
・Flyweight  オブジェクトの共有
・Proxy    代わりに処理する

って感じです。
今回も、どーいうことがいいたいのかを中心に書いていきます。
(順番は変えます。簡単なもんから説明していってます)




■Facade
 入り口を1つにする。これは、どっかのサーバーを呼び出すなんていうケースで、サーバー側のプログラム(呼び出し)は、今後増えていくなんていうようなケースのとき、とりあえず、

int execute(HashMap argMap);

というすべて、同じインターフェースにして、argMapの
キー"command" の値に呼び出すメソッドを設定、
それ以外のキーと、値に、その呼び出すメソッドで必要な引数を記述してもらって、
全部入り口はこのメソッドで共通にする

などというときに使います。





■Adapter
 いわゆるラッパーです。
 2つのメソッドが違うとき、たとえば、上記の例だと

 int execute(HashMap argMap);

 というメソッドが入り口で、呼び出すメソッドは int doJob(String arg1,String arg2);
 などと、違ったものかもしれません。このとき
 2つの違ったメソッドを呼び出し可能にするラッパーがAdapterです。





■Proxy
 代わりに処理する。
 たとえば、上記のサーバーを呼び出す場合、1回呼び出してしまったら、検索の場合、帰ってくる値は、2度目も3度目も同じでいいというケースがあります。(データベースのコードテーブルなどである)。
 こういうとき、
クライアント側にも
 execute(HashMap argMap);
というメソッドを用意し、このメソッドをみんな使ってもらい、
 このメソッド内では、
・新規のアクセスの場合は、サーバーアクセスして
 execute(HashMap argMap);
 を呼び出し、その結果を返すと同時に、どこかにプールしておく
・2度目以降のアクセスの場合、プールした内容の中にあれば、
 サーバーにアクセスしないで、プールした値を返す。

などというとき、クライアントのexecuteメソッドは、サーバーのexecuteメソッドのproxyであるといいます(HTTPのプロキシも、キャッシュを使って似たようなことしてる)





■Flyweight
 オブジェクトの共有。singletonのとき、1個のオブジェクトしか作らないで共有しましたが、あれとおなじです。ただし、1個だけじゃなくって、複数個作って共有することもあります。





■Bride
 機能のクラスと実装のクラスをわけます。
 なにがいいの、とか、どうやるの。。っていうのは、

 Java言語で学ぶデザインパターン入門
 第9章(121ページから)を見てください。かならずしもメリットだけとは限りません(と思います。クラスが深くなりやすい)。





■Composite
 違うものを1つの上位クラスにいれて、同じように扱う。
 いろんな種類のあるものを(再帰とかするため)、まとめて扱いたいとき、上位クラスをつくって、そいつから、それぞれの種類のクラスをextendしてやるものです。

 具体的に、違うものとしてファイルとディレクトリで、それを同じものとみなして再帰させるというプログラムが

 Java言語で学ぶデザインパターン入門

第11章(153ページから)にあります。





■Decorator
 付け足すとき、なんですけど、機能を追加する場合、包むことによって機能を追加する方法です。

 ファイルの読み込み(FileReaderクラス)のとき、バッファを使って行うようにしようとした場合、BufferedFileReaderというクラスを、FileReaderから継承してつくって、

 BufferedFileReader in = new BufferedFileReader(foo.in);

 ってしても、いいんだけど、もしそうすると、今度はソケットを使いたい場合、BufferedSocketReaderっていうクラスを作って、

 BufferedSocketReader in = new BufferedSocketReader("www.yahoo.co.jp",80);

ってやんないといけなくなってしまいます。
 さらに、BufferdFileReaderを機能追加した、ExtraBufferdFileReaderっていうのを考えたら、それのソケット対応のために、ExtraBufferedSocketReaderっていうのもつくって。。。

 入出力増えたらたいへんそう(>_<!)
 つまり、機能を継承で追加すると。。。。大変なことになる場合があります。

 java.ioでは、そういうことはしてなくて、FileReaderを、BufferedReaderがつつむことで、バッファリングした読み込み機能を追加する、つまり

BufferedReader in
= new BufferedReader(new FileReader("foo.in"));

とします。ソケットの場合
Socket socket = new Socket("www.yahoo.co.jp",80);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

ってします。このとき、BufferedReaderは、ファイル用、ソケット用とは、別れません。
これは、継承でなく、委譲という方法を使って実現しているのですが、これが、Decoratorのパターンです。

具体的に、これをどうやって実現するのかとか、継承と委譲の説明その他もろもろは
 Java言語で学ぶデザインパターン入門

第12章(169ページから)にあります。




 だんだん面倒になってきて、後のほうはみんな

  。。。を見てください

 になってしまった(^^;)

この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« 眞鍋かをりさんが、女性向けS... | トップ | Javaで基本操作(その8):... »
最新の画像もっと見る

JavaとWeb」カテゴリの最新記事