デザインパターン

 

1.          Iterator

(目的)

繰り返し処理を、オブジェクトの実装から切り離す

 

ReveseIteratorの実装には、

u    Iteratorインタフェースを拡張するのがよいのか

u    独自のインタフェースを定義するのがよいのか

u    Iteratorを親インタフェースにした上で、ForwardIteratoReverseIteratorInterfaceを拡張するのがよいのか

 

Bookshelfの集約を実現しているメンバを、配列から、ArrayListに変更する。

l         ArrayList(int initialCapacity)でサイズを指定した上で、初期化する。

l         public E get(int index)でコレクション内に保持されているBookオブジェクトをキャストして返す。

l         public boolean add(E o)ArrayListの末尾に、新しいBookオブジェクトを追加する。

 

2.          Adapter

(目的)

「既存のもの」を「必要なもの」に変換する。

 

Propertiesクラスのアダプタ、FilePropertiesクラスを実装する。ターゲットは、FileIOインタフェース。

l         readFromFileメソッド内で、loadメソッドにFileInputStreamを渡す。

l         writeToFileメソッド内で、storeメソッドにFileOutputStreamを渡す。

l         getValueメソッドは、getPropertyメソッドを変換する。

l         setValueメソッドは、setPropertyメソッドを変換する。

 

3.          Template Method

(目的)

スーパークラスで処理の枠組みを定め、サブクラスで具体的内容を決める。

 

4.          Factory Method

(目的)

インスタンス作成の枠組みを定める。

 

5.          Singleton

(目的)

インスタンスが一つしか作られないことを保証する。

 

6.          Prototype

(目的)

インスタンスのクローンを作るのに、作成済みのインスタンスを利用する。

 

Tips IncompatibleClassChangeErrorは、クラスの定義を変更した場合などに起こる。

例えば、インタフェースとして定義しておいたクラスを抽象クラスに変更して、関連するクラスを再構築しなかった場合などにも起こる。

 

clone():      protectedメソッドなので、作成済みのインスタンスしか、clone()メソッドは使えない。

              Cloneable(マーカ)インタフェースを実装する必要がある。

              clone()のフィールドのコピーは、シャロウコピー(浅いコピー)

              clone()をオーバーライドする場合は、super.clone()を忘れてはならない。

             

9.          Bridge

(目的)

インタフェース(実装)とサブクラス(機能)の上手な使い分け、およびそれらの橋渡し。

 

10. Strategy

(目的)

アルゴリズムの切り離し。アルゴリズム部分はAPIJava内ではインタフェース)を介して、呼び出す。

 

11. Composite


(目的)

異なる型(例:ファイル)を含む再帰的構造(例:ディレクトリのツリー構造)の抽象化。

 

(ポイント)

-         再帰的構造内の部品(ファイルおよびディレクトリ)はともにエントリ抽象クラスから操作する

-         ディレクトリ内に存在する、サブティレクトリはArrayList<Entry>として、配列型のメンバとして実装することで再帰的に呼び出し可能

-         メソッドによっては配列型メンバを介して掘り下げながら実行するものを必要に応じて実装(例えば、そのディレクトリ全体のサイズを表示したいような場合)

 

12. Decorator

(目的)

飾りと中身を同じように扱えるようにする。

 

(ポイント)

飾りの中に、一段下の飾り(または中身)を、メンバに持っておき、依頼を受けた作業の、実際の部分はそのメンバに委譲する。

最終的な作業は、最も内側に位置する中身が行う。

(あたかも客からの仕事の依頼に対して、元請けが自分がするかのように見せかけておいて、内実全てを下に、下にと振っていって、最終的に一番の下請けが仕事をするかのように。。)

 

13. Visitor

(目的)

処理とデータ構造の分離

 

 

(ポイント)

-         ConcreteElementelement.accept(visitor)による受入れと、ConcreteVisitorvisitor.visit(element)による訪問の組合せで実際の処理が決まる。これをダブルディスパッチという。

-         accept(Visitor v)メソッドの実装は、

v.visit(this);

  のように、この場合のthisであるConcreteElement(自分自身)を引数としてvisit()メソッドを呼び出すだけになるようなものが多い。

 

サービス業者(掃除業者、電気業者)を家(一軒家、マンション)によび、サービス(掃除業者なら部屋の掃除、電気業者なら配電盤の修理など)をしてもらうようなイメージ。呼ぶ業者によってしてもらうサービスが違えば、業者の方も訪問する家の形状や状態によってそのサービスを適宜調整する、しかし本質的に達成したい目的は同じといった場合に有用なパターンである。

 

14. Chain Of Responsibility

(目的)

処理のたらい回し。処理をするクラスの中にそのクラスで処理できない場合に処理をゆだねるクラスを持っておき、いざというときに処理をたらい回しにする。

 

15. Facade

(目的)

シンプルな窓口。複雑だが、決まった順番での呼び出し等決まりきった処理をひとまとめのメソッドにして、外部からはそのメソッドだけを呼び出せばいいようにする。

 

 

16. Mediator

(目的)

処理の判断の一極集中。やり取りは1つのMediatorと各Colleagueの間でのみ行われ、Colleague同士がやり取りはしないので、ロジックの実装が容易になる。

 

18. Memento

(目的)

状態を保存する。状態のセーブ(Save)やリストア(Restore)を実現し、アンドゥ(Undo)やリドゥ(Redo)などの処理を可能にする。

 

19.State

(目的)

状態をクラスにする。状態による振る舞いの違いを、ポリモーフィズムで実現する。

 

20.Flyweight

(目的)

メモリにロードされたインスタンスを共有する。

 

21.Proxy

(目的)

代理人をたてる。本人は本当に必要なときまで呼ばない。本人を実行するには、まず重たくて起動に時間のかかるインスタンスをロードする必要があるため、最初からそれをせず必要なときまで後回しにしておく。

 

 

 

(参考文献)Java言語で学ぶデザインパターン入門(結城 浩著)