目次へ |
No. | パターン名 | 目的 |
---|---|---|
1 | Iterator | Listのような集合オブジェクトの各要素に順次アクセスする方法の実装を外部クラスに委譲 |
2 | Adapter | インタフェースに互換性の無いクラス同士を組み合わせることを目的としたパターン |
3 | Template Method | ある処理のおおまかなアルゴリズムをあらかじめ決めておいて、そのアルゴリズムの具体的な設計をサブクラスに任せること |
4 | Factory Method | 生成するインスタンスの種類が多くなりそうな場合に、 インスタンス生成の責務を外に切り出して保守性を高める (オブジェクト生成を疎結合化) |
No. | パターン名 | 目的 |
---|---|---|
5 | Singleton | そのクラスのインスタンスが1つしか生成されないことを保証 |
Monostate | 全てのインスタンスが状態を一つしか持っていないように振る舞う | |
6 | Prototype | 「原型」となるインスタンスから新しいインスタンスを生成するパターン |
7 | Builder | インスタンス生成手順が複雑な場合やインスタンス生成構成が複雑な場合に生成を簡略化 |
8 | Abstract Factory | 関連するインスタンス群を生成するための API を集約することによって |
9 | Bridge | 機能のクラス階層と実装のクラス階層を別々に管理し結びつける(橋渡しする)パターン。クラスを複数の方向に拡張させることを目的とする。 |
10 | Strategy | アルゴリズムの部分をカプセル化することで、アルゴリズムを動的に切り替えることができるパターン |
11 | Composite | ディレクトリとファイルなどのような、木構造を伴う再帰的なデータ構造を表す |
12 | Decorator | 既存のオブジェクトを新しい Decorator オブジェクトでラップするパターン |
13 | Visitor | データ構造と処理を分離するパターン |
No. | パターン名 | 目的 |
---|---|---|
14 | Chain of Responsibility | 複数のオブジェクトを鎖状に繋ぎ、あるオブジェクトが要求を処理するまで、チェーンに沿って要求を渡していくパターン。 |
15 | Facade | 複雑な処理を簡単に呼び出すことを目的としたパターン |
16 | Mediator | クラスの複雑なやりとりを一極集中するためのパターン |
17 | Observer | インスタンスの状態が変化した際、そのインスタンス自身が、「観察者」に状態の変化を「通知」する |
18 | Memento | インスタンスの状態を表す役割を導入して、カプセル化の破壊に陥ること無く保存と復元を行う |
19 | State | 状態をクラスとして表現しクラスを切り替えることにより状態の変化を表すパターン。(状態に応じて振る舞いを変える必要がある場合に有効) |
20 | Flyweight | 生成済みのオブジェクトを共有することで、リソースを無駄なく使うこと |
21 | Proxy | 身代わりとなるオブジェクトを通じて間接的に目的のオブジェクトにアクセスさせるためのパターン |
22 | Command | Commandパターンは、実行可能なアクション(コマンド)をオブジェクトとして扱い、コマンドの詳細をカプセル化するパターン |
23 | Interpreter | 定義された種類の問題を素早く解くために、ドメイン固有言語を実装 |
記号 | アクセス制御 | 解説 |
---|---|---|
+ | public | どのクラスからも見える |
- | private | そのクラスだけから見える |
# | protected | そのパッケージとサブクラスから見える |
~ | なし | そのパッケージだけから見える (package) |
目的 | Listのような集合オブジェクトの各要素に順次アクセスする方法の実装を外部クラスに委譲 |
---|---|
クラス図 |
Iterator (反復子) |
要素を順番にスキャンしていくインターフェースを定める役
|
|||||
---|---|---|---|---|---|---|
ConcreteIterator (具体的な反復子) |
Iteratorを実装する役 | |||||
Aggregate (集合体) |
Iteratorを作りだすインターフェースを定める役 | |||||
ConcreteAggregate (具体的な集合体) |
Aggregateが定めたインターフェースを実装する役 (ConcreteIteratorのインスタンスを作る) |
目的 | ある処理のおおまかなアルゴリズムをあらかじめ決めておいて、そのアルゴリズムの具体的な設計をサブクラスに任せること | ||
---|---|---|---|
メリット |
スーパークラスのテンプレートメソッドで大きな流れが記述されるので サブクラス側で流れ記述する必要がなく、具体的な肉付けのみ記述すれば良い * あまりに継承を複雑化してしまうとコードを追いにくくなるので、継承は1階層ぐらいに留めておくべき |
||
クラス図 |
|
AbstractClass (抽象クラス) |
テンプレートメソッドを実装。また、そのテンプレートメソッドで使う抽象メソッドを宣言。 テンプレートメソッドで、抽象メソッドを利用した大きな流れを定める |
---|---|
ConcreteClass (具象クラス) |
AbstractClass役で定義されている抽象メソッドを実装。 ここで実装したメソッドは、AbstractClass役のテンプレートメソッドから呼び出される。 |
目的 | 生成するインスタンスの種類が多くなりそうな場合に、 インスタンス生成の責務を外に切り出して保守性を高める (オブジェクト生成を疎結合化) オブジェクトを生成する際のインタフェースだけを規定し、実際にどのクラスをオブジェクト化するかはサブクラスにまかせる。 |
---|---|
メリット |
オブジェクトの生成処理と使用処理を分離し、利用者側から隠すことでクラス間の結びつきが低くなる。 これにより、再利用性が高まり柔軟な対応が可能となる。 インスタンスの生成の前や後に色々な処理をやる必要がある場合、それをクライアント側ではなく、Factoryクラス側
|
クラス図 |
Creator (作成者) |
このパターンで生成されるインスタンスが持つべきインターフェースを定める抽象クラス。 実際に生成する ConcreteProduct 役については何も知らない。 |
---|---|
Product (製品) |
Product役を生成する抽象クラス。 |
ConcreteCreator (具体的製品) |
具体的な製品を作るクラスを定める。 ConcreteProduct のインスタンスを生成する。 |
ConcreteProduct (具体的製作者) |
具体的な製品を定める。 |
目的 | そのクラスのインスタンスが1つしか生成されないことを保証 |
---|---|
メリット |
インスタンスを使いまわすことにより負荷を軽減 扱い次第では、グローバル変数のように機能させることもできる (グローバル変数と同様の問題を引き起こす危険性をはらむ→どこで値が書き換わるか予測できないなど → パッケージ指定により問題を軽減) |
注目点 |
同じ型のインスタンスが private なstaticフィールドとして定義 コンストラクタの可視性が private 同じ型のインスタンスを返す getInstance() がクラス関数として定義 |
クラス図 | |
Singleton |
唯一のインスタンスを得るためのstaticメソッドを持つ このメソッドは常に同じインスタンスを返す |
目的 |
全てのインスタンスが状態を一つしか持っていないように振る舞う mono(モノ) = 「1つの」、state(ステート) = 「状態」 |
---|---|
メリット | インスタンス自体はいくらでも作成できるがインスタンスが1つしか存在しないのと同等な状態を作ることができる |
クラス図 | |
Monostate |
クラスのすべてのフィールドがクラスフィールド(static) そのフィールドにアクセスするインスタンスメソッドがある |
Singletonパターン |
「構造」に着目 インスタンスをたった一つしか作らせない「構造」 必ずインスタンスが一つになるような構造にしなければならない
|
||||||
---|---|---|---|---|---|---|---|
Monostateパターン |
「振る舞い」に着目 インスタンスを生成する方法に制約はなく、あくまでオブジェクトの「振る舞い」がどのインスタンスにおいても同じであるということを規制
|
目的 | 「原型」となるインスタンスから新しいインスタンスを生成するパターン (Prototype : 「模範」「原型」) |
---|---|
メリット |
多くなりすぎたクラスの管理が容易になる (生成オブジェクトを同一クラス(Prototype) のインスタンスにすることができる為) 生成の複雑なインスタンスをコピーできる フレームワークと生成するインスタンスを分けられる オブジェクトの生成処理を隠蔽できる クラス同士の関係を緩くする |
利用シーン |
インスタンスをコピーして処理を変更したい場合 複雑な生成過程を経たインスタンスをコピーしたい場合 テンプレートインスタンスをコピーすることで処理が楽になる場合 |
クラス図 |
注意点 |
Prototypeパターンを適用する場合、「浅いコピー」と「深いコピー」を意識して実装する必要がある Prototypeパターンを用いるときには、「複製が容易なオブジェクト」であることが大切になる
|
||||
---|---|---|---|---|---|
Javaのclone |
|
Prototype (原型) |
インスタンスをコピーして新しいインスタンスを作るためのメソッドを定める |
---|---|
ConcretePrototype (具体的な原型) |
インスタンスをコピーして新しいインスタンスを作るメソッドを実装 Javaの場合、cloneメソッドを呼び出す |
Client (利用者) |
インスタンスをコピーするメソッドを利用して、新しいインスタンスを作る |
PrototypeManager |
プロトタイプが実行時に動的に生成されたり、破壊されたりする場合、利用可能なプロトタイプを登録しておくための機構 与えられたキーに合致するプロトタイプを返す連想配列になっており、キーとともにプロトタイプを登録するオペレーションや、登録を削除するオペレーションを持つ このためクライアントはプロトタイプを直接扱わずに済み、プロトタイプの追加や利用のためのコード修正の必要がない |
目的 | インスタンス生成手順が複雑な場合やインスタンス生成構成が複雑な場合に生成を簡略化 | ||||
---|---|---|---|---|---|
メリット |
同じ作成過程で異なる表現形式の結果を得られる Productオブジェクトの生成過程や生成手段を隠し、局所化できる |
||||
Template Methodパターン との違い |
インスタンス生成の役割を誰が負うのかというところ
|
||||
クラス図 |
Director (監督) |
Builder役のインターフェースを使ってインスタンスを生成 ConcreteBuilder役に依存したプログラミングは行わない Builder役のメソッドのみ使用 Construct()に生成過程を記述 |
---|---|
Builder (建築者) |
インスタンスを生成するためのインターフェースを定める 実際のインスタンス生成で呼び出されるメソッド(生成手段のメソッド)を定義 |
ConcreteBuilder (具体的建築者) |
Builderのインターフェースを実装。 実際のインスタンス作成で呼び出されるメソッドを定義。(具体的な生成手段) 最終的に出来た結果を得るためのメソッド(getResult())を用意。 |
目的 |
関連するインスタンス群を生成するための API を集約することによって
|
||||
---|---|---|---|---|---|
Factory Methodパターン との違い |
|
||||
メリット |
複数のモジュール群を再利用できる 整合性を必要とされる一連のオブジェクト群を間違いなく生成 (正しいインスタンス化の方法が1箇所にまとめられている) インターフェース(API)だけを使って、製品にまとめられるため (具体的な実装には注目しない) 内部で何をしているか気にかける必要はなく、どんな製品を作る場合も、同じ操作で生成 |
||||
デメリット | 後から製品 (Product) を追加することが困難 (具体的な工場全てに修正を加えることになる) |
イメージ | |
---|---|
クラス図 |
AbstractProduct (抽象的な製品) |
AbstractFactory役によって作り出される抽象的な部品や製品のインターフェース (API) を定める。 |
---|---|
AbstractFactory (抽象的な工場) |
AbstractProduct役のインスタンスを作り出すためのインターフェース (API) を定める。 |
Client |
AbstractFactory役とAbstractProduct役のインターフェース (API) だけを使って仕事を行う役。 具体的な部品や製品や工場については知らない。 |
ConcreteProduct (具体的な製品) |
AbstractProduct役のインターフェース (API) を実装。 |
ConcreteFactory (具体的な工場) |
AbstractFactory役のインターフェース (API) を実装。 |
目的 | 機能のクラス階層と実装のクラス階層を別々に管理し結びつける(橋渡しする)パターン。クラスを複数の方向に拡張させることを目的とする。 | ||||
---|---|---|---|---|---|
クラス階層 |
|
||||
利用シーン |
あるプログラムにOS依存の部分があり、Windows版、Mac版、UNIX版に分かれている場合 OS依存の部分を "実装のクラス階層" で表現し、"機能のクラス階層" に機能を追加する |
||||
クラス図 |
Abstraction (抽象化) |
"機能のクラス階層"の最上位のクラス。 Implementor役のメソッドを使って、基本的な機能だけが記述されているクラス。 このインスタンスは、Implementor役を保持する(impl : Implementor)。 |
---|---|
RefinedAbstraction (改善した抽象化) |
Abstraction役に機能を追加した役 |
Implementor (実装者) |
"実装のクラス階層"の最上位クラス。 Abstraction役のインターフェースを実装する為のメソッドを規定する役。 |
ConcreteImplementor (具体的な実装者) |
Implementorのインターフェースを実装する役。 |
目的 |
アルゴリズムの部分をカプセル化することで、アルゴリズムを動的に切り替えることができるパターン
|
---|---|
メリット |
アルゴリズムをカプセル(クラス)化できる
|
利用シーン |
元のアルゴリズムを改良したアルゴリズムの速度を比較したい場合 ゲームの難易度に合わせて、戦略アルゴリズムを変える場合 動作環境に応じて処理を変えたい場合
* 継承を使用してアルゴリズム処理の差分を実装しているような処理や
switch文、if文などの分岐処理を多用しているようなクラスが存在する場合にも採用を検討 |
クラス図 |
ポイント | Contextのメンバ変数に内蔵したい戦略 (Strategy) を保持し、個々の振る舞いは派生クラス(ConcreteStrategy)で実現 (コンポジション、委譲) |
---|---|
コンポジション | あるクラスの機能を持つクラス |
委譲 |
特定のクラスの機能を、自分が作るクラスにも持たせたい場合 継承を使わずフィールドとしてそのクラスを持ち、そのクラスのメソッドを呼び出す。 そうすることで、クラスに他のクラスの機能を組み込むことができる。 主な利用用途として、インスタンス間の緩やかな関係を築く場合に使われる。 |
Strategy (戦略) |
戦略を利用するためのインターフェース (API) を定める。 |
ConcreteStrategy (具体的な戦略) |
Strategy役のインターフェース (API) を実装。 ここで具体的な戦略 (アルゴリズム) を実際にプログラミングする。 |
Context (文脈) |
Strategy役を利用する役。 ConcreteStrategy役のインスタンスを持ち、必要に応じてそれを利用。 (呼び出すのはStrategyのインターフェース (API) ) |
目的 |
単一のオブジェクトとその集合のどちらも同じように扱えるようにするためのパターン ディレクトリとファイルなどのような、木構造を伴う再帰的なデータ構造を表す Composite : 意味 - 混合物、複合物 |
---|---|
メリット |
登場するオブジェクトは、「枝」と「葉」で、共通のインターフェースを実装している。 そのため、枝と葉を同様に扱うことができる (同じAPIでアクセスできる)。 木構造の枝葉を同一視する事ができるため、新しい枝(Compositeクラス)を簡単に追加出来る。 *データ構造がきちんと木構造を保つようにしなければ、親子関係が循環してしまった場合 Component#operation() を実行した際に無限ループに陥ってしまう。 |
利用シーン | ファイルシステムのディレクトリツリーのように、木構造を持つデータ構造 |
クラス図 |
Component | 戦略を利用するためのインターフェース (API) を定める。 |
---|---|
Leaf (葉) |
Componentクラスのサブクラス。"中身"を表す役。 木構造の末端に位置するため、子に相当するオブジェクトを持たない。 |
Composite (複合体) |
Componentクラスのサブクラス。"容器"を表す役。 木構造の中で、任意枝に相当するクラスのため、子に相当するオブ ジェクトを持つことが出来る。 (Leaf役やComposite役を入れることが出来る) また、Componentクラスで定義された子オブジェクトへのアクセスAPIや追加・削除APIなども実装する。 |
目的 | 既存のオブジェクトを新しい Decorator オブジェクトでラップするパターン |
---|---|
メリット |
飾り枠と中身を同一視することで機能拡張がより柔軟にできる (飾り枠と中身が同一のインタフェースを持つ) オーバーライドせず、委譲を活用して振る舞いを装飾(拡張)できる 既存のオブジェクトに新しい機能や振る舞いを動的に追加できる 付加する機能が複数ある場合、それらを任意の順番で組み合わせることができる |
デメリット |
Decoratorパターンでは、すべてのクラスが同じインターフェースを持ため 具体的なクラスを後で1つ追加しようとした際、メソッドに引数を増やす必要が生じたり メソッドが投げる可能性のある例外が増えることにより これまでに作ったDecoratorも含め、すべてのクラスを修正しなくてはならない。 多数の小さなクラスができる可能性があり、乱用すると複雑になる可能性がある。 Decoratorパターンは機能を細分化し、たくさんのクラスに分割できる点が特徴であるため、クラスの数が多くなる。 一般にインターフェースの変更は影響が大きいが、Decoratorパターンでは特に修正範囲が広くなりやすい。 |
クラス図 |
Component (部品) |
機能を追加するときの中心になる役。 機能拡張するメソッドのインタフェースを定義する。 |
---|---|
ConcreteComponent (装飾者) |
Component役のインターフェースを実装する具体的な核となるクラス。 基本となる機能を実装する。 |
Decorator (複合体) |
Component役 (Componentを実装しているオブジェクト - 飾る対象) を保持し Component役と同じインターフェースを持つ。 (※ 飾る対象となるのは、"ConcreteComponent"、"ConcreteDecorator") |
ConcreteDecorator (具体的な装飾者) |
具体的なDecoratorの役。 Decoratorのインタフェースを実装する。 ConcreteComponentに関する操作(Operation)を再定義する。 |
目的 | データ構造と処理を分離するパターン |
---|---|
メリット |
処理を構造から切り分けることで、処理は処理クラスの中に閉じ込め、処理の追加や変更に対する自由度を高めることができる
|
デメリット |
ConcreteElement役の追加は困難。 Element役はVisitor役に対して十分な情報を公開する必要があるが公開すべきでない情報を公開してしまうと、カプセル化が壊れたクラスになってしまう。 |
クラス図 |
Visitor (訪問者) |
データ構造の具体的な要素 (ConcreteElement役) ごとに、処理専門のメソッドを宣言する。 ( visit(xxxx)メソッド ) |
---|---|
ConcreteVisitor (具体的な訪問者) |
Visitor役のインターフェース (API) を実装。 個々のConcreteElement役ごとの処理を記述。 構造内のオブジェクト (ConcreteElement) を訪問(visit)し、処理を実行する。 |
Element (要素) |
Visitor役の訪問先を表す役。 訪問者を受け入れる accept メソッドを宣言。 acceptメソッドの引数にはVisitor役が渡される。 |
ConcreteElement (具体的な要素) |
Element役のインターフェース (API) を実装する。 visitメソッドの引数には、自分自身 (this)が渡される。 これにより、オーバーロードによるメソッド呼び出しが行われる。 |
解説 |
Visitorパターンにおいて大きな役割を持つのはVisitorとElementです。 この2つのインタフェースが協調して、処理の分離を実現しています。 Visitorは処理を定義するクラスです。 すべての処理は、このインタフェースを継承し、具体的な処理クラスを実装していきます。 また、Visitorでは、visit()メソッドを引数を変えて複数用意していますが、これは引数のクラスがConcreteElementAの場合とConcreteElementBの場合で、それぞれの処理を別々に分けて実装することが目的です。 一方、Elementでは、処理をしてくれるVisitorクラスを受け入れる玄関となるaccept()メソッドを定義しています。 accept()メソッドではVisitorクラスに処理対象となる自分自身(this)のインスタンスを渡し(オーバーロードによるメソッド呼び出し) それ以外のことをする必要はありません。 Elementから見たVisitorへの関わり合いを極力少なくすることで、Visitorの実装クラスの変更や追加に対するインパクトが小さくなります。 このVisitorとElementの関係は、しばしばダブルディスパッチと呼ばれます。 ダブルディスパッチとは「2重の呼び出し」という意味で、まずElementのaccept()メソッドを呼び出し、さらにVisitorのvisit()メソッドを呼び出すという2つのメソッド呼び出しを経て初めて行うべき処理が決まることからこう呼ばれます。 |
---|
目的 |
複数のオブジェクトを鎖状に繋ぎ、あるオブジェクトが要求を処理するまで、チェーンに沿って要求を渡していくパターン。 (Chain of Responsibility =「責任の鎖」=「責任」を負ったものが、「鎖」状につながれた状態) |
---|---|
イメージ | |
メリット |
要求側(Client)と処理実行側(ConcreteHandler)の結びつきが緩やかになる。
|
デメリット |
処理が遅くなる可能性がある。 (適切な処理を行うConcreteHandlerを順次探さなければならないため) |
クラス図 | |
---|---|
Handler (処理者) |
要求を処理するインターフェース (API)を定義。 内部にHandler型の「次の処理者」を保持しておき自分が処理できない要求がきたら、その人に任せる。 |
ConcreteHandler (具体的処理者) |
要求を処理する具体的な役。 Handlerクラスで定義されたAPIを実装 (具体的な処理) 。 |
Client (要求者) |
チェーンを構成しているConcreteHandler役に要求を出す役。 |
目的 |
複雑な処理を簡単に呼び出すことを目的としたパターン ファサード(仏) = 「建物の正面」の意 サブシステムに対する明確で簡潔なインタフェースを定義し、使いやすいようにその内部構造を隠蔽 |
---|---|
メリット |
あるAPIを呼び出すだけでサブシステムを利用できるようになる (複雑なものを単純に利用できる) クライアントとサブシステム、サブシステム同士の依存関係が緩くなる |
ポイント |
Facedeパターンはサブシステムの直接使用を妨げない。
Facedeクラスの利用は強制ではなく、必要であればサブシステムの機能を直接利用できる。
Facadeパターンでは処理の呼び出し口となるメソッドはstaticメソッド(クラスメソッド)として定義される
インスタンス化不要でメソッドの呼び出しができるので、ユーザは楽になる。
Abstract Factory パターンは Facade パターンの具体例と言える。
ConcreteFactory クラスが Facade クラスに相当。
|
クラス図 |
Façade (正面) |
システムを構成しているModules (その他の機能) のシンプルな窓口。 高レベルでシンプルなインターフェース (API) をシステム外部に提供。 |
---|---|
Modules |
それぞれの仕事を行うが、Façade役のことは意識しない。 Façade役から呼び出されて仕事を行うが、Façade役を呼び出すことはない。 |
Client (装飾者) |
Façadeパターンを利用する役。 |
目的 |
クラスの複雑なやりとりを一極集中するためのパターン (Mediator : 「仲裁人、調停者」の意) 複雑に絡み合った複数のオブジェクト間の関係を、必ず「仲介者」を介して処理を行う様にすることで単純かつ明快なインタフェースを提供 |
||||
---|---|---|---|---|---|
メリット |
通信するオブジェクト同士の依存関係を削減(お互いに直接的な参照をさせない)し、結合の度合いを低くする コントロールロジックは相談役の中にのみ記述される為、デバッグ・修正がしやすい。 処理が一箇所に集中されるため、不明瞭になりがちなオブジェクト同士の関係が明確になる |
||||
利用シーン |
複雑に絡み合う、多数のオブジェクト間の調整を行いながら処理をすすめる必要がある場合 GUIアプリケーションで特に効果的 |
||||
Facadeパターン との違い |
|
||||
クラス図 |
Mediator (調停者、仲介者) |
Colleague役と通信を行い、調整を行うためのインターフェース (API) を定める |
---|---|
ConcreteMediator (具体的な調停者、仲介者) |
Mediator役のインターフェース (API) を実装し、実際の調整を行う |
Colleague (同僚) |
Mediator役と通信を行うインターフェース (API) を定める |
FaçConcreteColleague (具体的な同僚) |
Collegue役のインターフェース (API) を実装 |
目的 |
インスタンスの状態が変化した際、そのインスタンス自身が、「観察者」に状態の変化を「通知」する Observer = 「観察者」 「観察者」は能動的に観察するのではなく、インスタンスから「通知」されるのを受動的に待っていることになる為 Publish-Subscribeパターンと呼ばれることもある (Publish = 「発行」、Subscribe = 「購読」) |
---|---|
メリット | 状態が変化する側が「通知」する仕組みを持つことで、観察者は常に観察しなければいけない状態から開放される |
利用シーン |
ユーザーが何らかの操作をするなどの外部イベントを待つ場合 オブジェクトの属性値の変化を待つ場合 Model View Controllerパラダイムの実装に使われることも多い MVC では、モデル・ビュー間のループに Observer パターンが使われる 通常、モデルの変化を引き金として、ビュー(オブザーバ)にそれを通知する |
クラス図 |
updateの 呼び出しが 2パターン |
|
---|
Subject (被験者) |
「観察される側」 Subject クラスはオブザーバのリスト(observers)を保持する。以下の関数を持つ:
|
---|---|
ConcreteSubject (具体的な被験者) |
具体的な「観察される側」を表現 状態が変化したら、そのことを登録されているObserverに伝える。 スーパークラス(Subject クラス)の Notify 関数を呼び出すことで、全オブザーバに状態変化を通知 |
Observer (観察者) |
Subject からの更新通知を受け取るupdateインタフェースを定義するクラス |
FaçConcreteOveserber (具体的な観察者) |
ConcreteSubject の状態変化の通知を受ける Subject の現在の状態を取得 |
目的 | インスタンスの状態を表す役割を導入して、カプセル化の破壊に陥ること無く保存と復元を行う |
---|---|
カプセル化の破壊 | 不用意に内部情報へのアクセスを許したため、そのクラスの内部構造に依存したコードがプログラムのあちこちにちらばりクラスの修正がしにくくなる状態 |
利用シーン |
テキストエディタやペイントソフトのように、操作をキャンセルして元の状態に戻す 「アンドゥ」機能などを実装したい場合 Memento : 英語で「記念品」「形見」を意味 Mementoパターンを利用すると
などを行うことが出来る。 |
クラス図 |
Originator (作成者) |
自分の現在の状態を保存したいときにMemento役を作る。 (createMemento) また、以前のMemento役を渡されると、そのMemento役の状態を元に、オブジェジェクトの状態を戻す処理を行う。 (restoreMemento) |
||||
---|---|---|---|---|---|
Memento (記念品) |
Originatorの内部情報をまとめる。 内部情報は、(内部状態を操作できる度合いの違う) 2種類のインターフェースを持つ この2種類のインターフェースを使い分けることで、オブジェクトのカプセル化の破壊を防ぐ
|
||||
Caretaker (世話をする人) |
現在のOriginator役の状態を保存したいときに、そのことをOriginator役に伝え Originator役はそれを受けてMemento役を作り、Caretaker役に返す。 Caretaker役はそのMemento役を、内部に保存する。 |
目的 |
状態をクラスとして表現しクラスを切り替えることにより状態の変化を表すパターン。(状態に応じて振る舞いを変える必要がある場合に有効) (「クラスの変化=状態の変化」) |
---|---|
ポイント | 状況(Context)に状態 (State) オブジェクトを保持し、状態による個々の振る舞いは派生クラス(ConcreteState)で実現 |
メリット |
条件(状態)に一致するか否かの処理は、条件分岐でも同じことを実現できるが、処理が複雑になったり、その状態の数が多い場合は後々の管理が大変になる。 状態をクラスとして表現することにより、上記問題が解消される。 また、状態を表す変数が1つのため、自己矛盾が起こらない。 |
クラス図 |
Strategyパターン との違い |
目的が異なる
|
||||
---|---|---|---|---|---|
State (状態) |
状態を表し、状態ごとに異なる振る舞いをするインターフェース (API) を定める。 このインターフェース (API) は、状態に依存した振る舞いをするメソッドの集まりになる。 |
||||
ConcreteState (具体的な状態) |
具体的な個々の状態を表現。 State役で定められたインターフェース (API) を具体的に実装。 | ||||
Context (状況、前後関係、文脈) |
現在の状態を表すConcreteState役を持つ。 Stateパターンの利用者に必要なインターフェース (API) を定める。 |
ConcreteState役で行う |
状態遷移を状態に依存した振る舞い
|
||||
---|---|---|---|---|---|
Context役で行う |
|
目的 | 生成済みのオブジェクトを共有することで、リソースを無駄なく使うこと |
---|---|
メリット |
同じオブジェクトを再利用することでメモリの使用量を抑え、インスタンス生成の処理を省き、効率的な処理になる 利用者側が得る結果は(再利用・新規生成問わず)全く同じであるため、利用者は内部構造を意識せずに使うことが出来る |
注意点 |
一度 FlyweightFactory に保存されたインスタンスは、不要になってもガベージコレクションの対象とならない。 (明示的にインスタンスへの参照を削除) |
利用シーン |
軽量化対象のクラスが, 不変なクラス (イミュータブル, immutable なクラス) の場合。 (共有しているものを変更すると複数箇所に影響が及ぶため)
|
クラス図 |
Flyweight (フライ級) |
普通に扱うとプログラムが重くなるので共有した方がよいものを表す役。 共有化の対象。 |
---|---|
FlyweightFactory (フライ級の工場) |
Flyweightを作る工場の役。 この工場を使ってFlyweight役を作ると、インスタンスが共有される。 |
Client (依頼者) |
FlyweightFactory役を使ってFlyweightを作りだし、それを利用する役。 |
目的 | 身代わりとなるオブジェクトを通じて間接的に目的のオブジェクトにアクセスさせるためのパターン | ||||
---|---|---|---|---|---|
メリット |
オブジェクトとその利用側との間に緩衝剤を用意することで、お互いを分離したり付加的な機能を追加できる 分離するということは、具体的なクラスに依存しないコードになる ProxyクラスとRealSubjectクラスは、どちらもSubjectインターフェース (API) を実装している為 必要なければRealSubjectを直接呼び出すこともできる |
||||
Decoratorパターン との違い |
|
||||
クラス図 |
Subject (主体) |
Proxy役とRealSubject役を同一視するためのインターフェース (API)を定める。 Subject役があるおかげで、Client役はProxy役とRealSubject役の違いを意識する必要がない。 |
---|---|
Proxy (代理人) |
Proxy役はClient役からの要求をできるだけ処理する。 自分だけで処理できない場合、RealSubject役に処理を任せる。 Proxy役は本当にRealSubject役が必要になってからRealSubject役を生成する。 Subjectで定められているインターフェース (API) を実装。 |
RealSubject (実際の主体) |
Proxy役で処理できなくなった場合に登場。 Proxy役と同様にSubject役で定められているインターフェース (API) を実装する。 |
Client (依頼者) |
Proxyパターンを利用する役。 |
Virtual proxy |
仮想プロキシ。生成コストのかかるオブジェクトの生成をできるだけ先送りする。(Proxyとして実体なしでオブジェクトを作成) インスタンスが必要になった時点で、生成初期化を行う。 例えば、画像イメージを扱うWebブラウザのようなプログラムで、はじめにイメージを表示させる必要がない場合、 はじめにページ内のイメージオブジェクトをProxyとして生成。 イメージを表示させるモードに替わったり、イメージがクリックされた時に、実体をロードして表示。 ページの初期表示のスピードの向上やプログラムのメモリ消費の節約になる。 |
---|---|
Remote proxy |
遠隔プロキシ。分散オブジェクトのようなネットワーク上の別のサーバのオブジェクトにアクセスする場合に IPアドレスやプロトコルなどのネットワークに関連した情報を隠して、プログラムからあたかもローカルなオブジェクトのように扱うパターン |
Protection (access) proxy | オブジェクトの保護するためのプロキシ。オブジェクトにアクセスする際、代理に通じて権限チェックなどの操作を行う |
Copy-on-write proxy | virtual proxyの特例。オブジェクトのクーロン操作をできるだけ先送りに |
Cache proxy | キャッシュプロキシ。生成コストのかかるオブジェクトの生成にキャッシュ機構によって提供 |
Firewall proxy | ファイアウォールプロキシ。ターゲットオブジェクトを悪意があるクライアントから隔離 |
Synchronization proxy | 同期プロキシ。マルチスレッド環境で同期する必要があるオブジェクトへのアクセス方法を提供 |
目的 |
Commandパターンは、実行可能なアクション(コマンド)をオブジェクトとして扱い、 コマンドの詳細をカプセル化するパターン |
---|---|
メリット |
要求の受付と要求に対応する処理を切り離して実装できる。 コマンドの追加や削除に対して柔軟になる。 クラスの再利用性を向上させる 要求と実際の実行を別のタイミングで実施することができる |
デメリット |
Command パターンを記述すると、関数を記述するよりコードが多くなる
* 使用するにはそれなりの理由がなければならない。
|
クラス図 |
利用シーン |
イベント駆動型の設計を行う場合 (処理をカプセル化しているため、イベントの起こり方には左右されない)
Undo、Redo、ログの記録、トランザクション、プログレスバー、ウィザード、
既存のコードを修正することなく機能拡張を行いたい場合GUI のボタンとメニューの項目、スレッドプールをサポートしたい場合 非同期でアクションを実行したい場合。キューなどに入れて異なるタイミングで実行する 抽象化された汎用的なコンポーネントを構築したい場合 コマンドオブジェクトそのものを他のリソースで使用したい場合 |
---|---|
Command (命令) |
命令のインターフェース (API) を定義する。 。 |
CocreteCommand (具体的な命令) |
Command役のインターフェース (API) を実装。 |
Receiver (受信者) |
Command役が命令を実行するときに対象となる役。 |
Client (依頼者) |
CocreteCommand役を生成し、その際にReceiver役を割り当てる役。 |
Invoker (起動者) |
命令の実行を開始する役。 Commandで定義されているインターフェース (API) - execute() を呼び出す。 |
目的 |
定義された種類の問題を素早く解くために、ドメイン固有言語を実装
|
---|---|
メリット | 特化言語は汎用の言語よりも数倍から数百倍高速に問題を解ける場合が多い |
利用例 |
データベースに特化した問い合わせ言語(SQLなど) 通信プロトコルを記述するために良く用いられる特化したコンピュータ言語 特化言語を導入した汎用のコンピュータ言語 |
クラス図 |
コード実行手順 |
1の字句解析と2の構文解析がおこなわれた結果は、木構造(Abstract Syntax Tree)として表すことができる Interpreterパターンは、構文木を処理するための最適なパターン |
---|---|
AbstractExpression (抽象的な表現) |
構文木のノードに共通のインターフェース (API) を定める役 |
TerminalExpression (終端となる表現) |
AbstractExpressionクラスのサブクラスで、構文木の葉に相当する末端の規則を表す |
NonterminalExpression (非終端となる表現) |
AbstractExpressionクラスのサブクラスで、構文木の節に相当 内部には、他の規則へのリンクを保持 (childExpressions - TerminalExpressionオブジェクト or NonterminalExpressionオブジェクト) |
Context (文脈、前後の関係) |
構文木を処理するために必要な情報を提供 |
Client (依頼者) |
構文木を組み立てるために、TerminalExpressionやNonterminalExpressionを呼び出す。 |