デザインパターンに関する備忘録

自分の自分による自分のための、デザインパターン23種を一言で整理して覚える試み。
「組み込みのC言語に応用するとしたら」という観点・目的による。
 (つまり覚えるためのメモであってデザインパターンの解説ではないので参考にしないようにお願いします。)

◆生成に関するパターン◆

【Builder パターン】
インスタンスを生成する際、生成する手順を定めたクラス(Director)と実際に生成作業を行うクラス(Builder)を用意する事で「生成手順を変更せずに生成物を変更する」ということを可能にする。


【Factory Method パターン】
インスタンス生成の「工場」。
インスタンス生成のためにnewを使う代わりに、一旦インスタンス生成用のクラス(工場)を用意し、その工場からインスタンスを生成させる事で柔軟性を持たせる。


【Abstract Factory パターン】
抽象化した部品を複数使って抽象化した生成物を作る工場を用意し、その工場を具体化して使用することで生成過程を隠蔽する。


【Prototype パターン】
あるクラスのインスタンスを生成しメンバー変数などをセットした後、「そのメンバー変数も同一のコピーとなるインスタンス」を生成する。
「複数のインスタンスを生成→それぞれのインスタンス一つ一つに同一のメンバー変数をセットする」よりも「インスタンスを一つ生成しメンバー変数をセットしプロトタイプを作る→プロトタイプのコピーを生成する」の方が、ラク。


【Singleton パターン】
コンストラクタをprivateにし、インスタンスの生成をさせないことで「このプログラム内にこのクラスのインスタンスは一つだけ」を保証する。
プログラム全体が関わる管理変数の塊なんかを複数作ってしまって混乱したりしないようしたいときに。



◆構造に関するパターン◆

【Adapter パターン】
アプリとドライバの間に挟まる「アダプタ」。
アプリが呼び出すドライバが変更され、かつそのドライバのインターフェースが変わる場合に、アプリ側を変更する代わりにアダプタを設け、そのアダプタ内でインターフェースの違いを吸収する。


【Bridge パターン】
機能と実装を分離し、それをつなぐための「橋」。
機能と実装を分離する(実装を一旦別クラスとし、それを機能はそれを持つ)ことで、機能を継承しても既に作った実装をそのまま使用できる。


【Composite パターン】
「容器と中身を同一視する」。
ファイルシステムを実装するような時、フォルダクラスもファイルクラスも共通のインターフェースを実装し、拡張性を持たせる。


【Decorator パターン】
既存の機能に追加の機能を「装飾」する。
既存のクラスを変更したり、また色々な機能を別途追加する事でクラスが煩雑になることなく機能を追加する。


【Facade パターン】
「窓口」。
一つのことを行うために複数の機能を使用する場合、その複数の機能の取りまとめ役を置く事で構造を簡潔にする。
アプリ-ドライバ間にミドルを置くようなもの。


【Flyweight パターン】
「フライ級」=軽いプログラム。
FactoryをSingletonにすることで無駄なインスタンス生成をしないようにし、消費するリソースを減らす。


【Proxy パターン】
「代理」。
あるクラスの代理のクラスを立て、普段はその代理のクラスを使い、その代理のクラスができないことは代理のクラスが元のクラスを呼んで解決する。



◆振る舞いに関するパターン◆

【Chain of Responsibility パターン】
「責任の鎖」。
同じような処理を行える複数のクラスがあった場合に、そのクラスに「処理が可能かどうかの判断」を加えることで「そのクラスで処理が可能であれば行う、処理ができなければ他のクラスに回す」というチェーンを構築する。


【Command パターン】
「コマンドを値で定義し、その値を渡してifやswitchの分岐で実行するようなクラス」を、「それぞれのコマンド内容を型を揃えて個別に作り、それを呼び出す」ということで拡張性を持たせる。
Cで言えば関数テーブルによる処理の呼び出しに近いか。


【Itarator パターン】
リストに対するインターフェース。
クライアントとリスト本体との間に入って「先頭要素へのアクセス」「末尾要素へのアクセス」「次の要素へのアクセス(要素の有無)」「前の要素へのアクセス(要素の有無)」などを提供する事で、リストの変更に柔軟性を持たせる。
繰り返す事でリストを走査するので「反復子(Iterator)」。


【Mediator パターン】
「仲介者・調停者」。
複数のオブジェクトをインスタンスとして持ち、それぞれの情報を把握した上で処理を行う。形的には各種アプリとアプリ管理の関係に近い。


【Memento パターン】
「記念品」。
ある時のインスタンスの状態の記録・復元を、インスタンスの内部変数操作を外部に許可せずに(カプセル化を壊さずに)行う。
(内部的に内部変数のコピー作っておいて、そのコピーへのセット関数(記録)とコピーを本体へセットする関数(復元)があれば同等なのでは、という気がする)


【Observer パターン】
「観察者」。
観察者という名前だけれど、実際には観察対象が観察者へ通知を送るという形を取る。


【State パターン】
「状態」をクラスとして実装する。
状態によって動作をswitch文で分岐させるということが良くあるが、その状態をクラスとして実装することでその分岐を取っ払う事ができ、状態分岐の追加も容易に行える。
(switch文→関数テーブル→関数ポインタによる処理切替、みたいな進化を考えると解りやすいかもしれない)


【Strategy パターン】
「戦略」。
ある機能の「やり方(戦略)」に相当する部分を別クラスとして実装し、必要に応じて切り替える。
Stateパターンと似ているが、Stateパターンは「機能そのものを状況によって分ける(アウトプットが変わる)」が、Strategyパターンは「機能そのものは変わらず、機能を満たすアルゴリズムの変更を行う(アウトプットは変わらず)」の違いがある。(本当か?)


【Template Method パターン】
「処理の大まかな流れ(テンプレート)を決める」→「サブクラスで各処理の詳細を実装する」。
実装テクニックというより設計のやり方の一つ。アプリの実装をコメントによるスケルトンで大まかに行って、その後詳細実装を行うというやり方に近い。
JavaやC++であればその「大まかな流れを決める」という部分にオーバーライドで柔軟性を出せる。


【Visitor パターン】
「訪問者」。
訪問者は訪問先に合わせて振る舞いを変えるが、訪問先(クライアント)は訪問者が変わっても特に意識することなく処理をお願いする。ダブルディスパッチにより実装。


【Interpreter パターン】
特定の問題に対し、それ専用のミニ言語を実装する。構文解析。
(「構文解析の良い作り方」としてInterpreterパターンを解説しているところがあったり、「何らかのミニ言語を実装する事全般がInterpreterパターンであり、構文解析はその代表例」と解説しているところがあったり。)


参考

デザインパターン | TECHSCORE(テックスコア)
Programing Place デザインパターン編
デザインパターン - オブジェクト指向設計 - [Syboos.jp]

C言語でデザインパターン実装を試みてるサイトがあったので追加。
C言語によるデザインパターン
デザインパターンの骸骨たち (RE-BONE) with C


memo.

生成系のパターンはそもそも生成の概念が無いC言語に応用するのは難しいが、初期化部分の実装のテンプレートのようなものと捉えると応用が利くかもしれない。

2013年11月12日 シゴト・ジツ トラックバック:0 コメント:0

<< 2013.11.13 - 19 | むなかた思考TOP | 2013.09.11 - 23 >>












管理者にだけ公開する