はじめに
本記事は「オブジェクト指向シリーズ」の第4回目の記事である.
「オブジェクト指向シリーズ」では,私がオブジェクト指向について勉強する中で特に重要であると思ったトピックについてまとめている.
誰かの勉強の際の手助けになれば幸いであるが,誤りがあれば以下に記載されているいずれかのSNSにご連絡いただけるとありがたい.
デザインパターンとは
プログラミング言語やアプリケーションの適用分野によらず,様々な場面で繰り返し現れるクラス構造に名前を付けてパターン化した「設計のパターン」である.
デザインパターンは,機能拡張や再利用がしやすいソフトウェアを作るために先人が工夫したノウハウ集となっており,デザインパターンを知っていることでいい設計をスムーズに進められる.
GoFのデザインパターン
デザインパターンという言葉が使われるようになったきっかけは,1995年に出版されたGoF(4人の著者がGang of Fourと呼ばれた)本である.
GoF本の中では23種類のデザインパターンが取り上げられており,それぞれ典型的に表れる課題に対して,3~5程度のクラスを組み上げて作る解法を示している.
以下にGoFのデザインパターンの一覧を示す.
No | パターン名 | 概要 |
---|
1 | Iterator | 一つ一つ数え上げる |
2 | Adapter | 一皮かぶせて再利用する |
3 | Template Method | 具体的な処理をサブクラスに任せる |
4 | Factory Method | インスタンス作成をサブクラスに任せる |
5 | Singleton | たった一つのインスタンスを使いまわす |
6 | Prototype | コピーしてインスタンスを作る |
7 | Builder | 複雑なインスタンスを組み立てる |
8 | Abstract Factory | 関連する部品を組み合わせて製品を作る |
9 | Bridge | 抽象と実装を分ける |
10 | Strategy | アルゴリズムをカプセル化し,入れ替え可能にする |
11 | Composite | 再帰的な木構造を表現する |
12 | Decorator | インスタンスに対し,動的に付加機能を追加する |
13 | Visitor | オブジェクトの構造と振る舞いを分離する |
14 | Chain of Responsibility | 責任のたらいまわし |
15 | Facade | 複数のサブシステムの窓口となるインターフェースを提供する |
16 | Mediator | 相手は仲裁人一人だけで,仲裁人を介してオブジェクト間でやりとりする |
17 | Observer | オブジェクトの状態変化を通知する |
18 | Memento | オブジェクトの状態を保存する |
19 | State | オブジェクトの状態を変化させ,それに伴って振る舞いを変化させる |
20 | Flyweight | 多数のインスタンスを共有し,インスタンス構築負荷を減らす |
21 | Proxy | 共通のインターフェースを持つインスタンスを内包し,内包されたインスタンスへのアクセスを制御・代理する |
22 | Command | 命令を呼び出すオブジェクトと,命令実行するオブジェクトを分離する |
23 | Interpreter | 文法規則をクラスで表現する |
デザインパターンのグループ分け・ユースケース
生成に関するパターン
- Factory Method
- Singleton
- 1つのインスタンスを使いまわす
- ユースケース
- 普遍的に世界に1つしか存在しないもの
- 数学関数,時刻,,
- Prototype
- 原型となるプロトタイプからインスタンスを生成
- SingletonとPrototype
- 原型は同じだが,複数のインスタンスが必要 ⇒ Prototype
- 1つのインスタンスだけで十分 ⇒ Singleton
- ユースケース
- 共通で複数回使われるインスタンスで,それを用意するコストが高いもの
- Builder
- 複雑な(オブジェクト構築に必要な要素が多い)インスタンスの組み立て
- 複雑なインスタンスでない場合は,Factory Method
- ユースケース
- Abstract Factory
- 関連するオブジェクトを抱えたインスタンス生成
- Builderと異なる点は,同じ構成となるようなオブジェクトかどうか
- Builderの例に挙げた食塩水と同じ構成を取るインスタンスが複数存在する場合は,Abstract Factoryでもよい
- ユースケース
- Windows PCとMacBook PC
- 各PCが抱えている関連オブジェクト:キーボード,ディスプレイ
構造に関するパターン
- Adapter
- インターフェースを一皮かぶせて内部実装の再利用
- ユースケース
- 状況:OSに依存しているが,機能としては同様のメソッドが存在する
- 実現したいこと:それぞれ用のメソッドを利用するための共通のインターフェースをかぶせることで,メソッド利用者からはどのOS用のメソッドを利用するときでも同じように呼び出せるようにする
- Bridge
- 抽象側と実装側を切り分け,独立
- ユースケース
- 実装側で依存性が強いもの(OS依存など)があり,実装側に互換性が無く,インターフェースを用意できない ⇒ Adapter
- 実装側に共通のインターフェースを用意できる ⇒ Bridge
- Composite
- 再帰的な木構造を表現
- ユースケース
- ファイルシステム
- 枝 ⇒ ディレクトリ,葉 ⇒ ファイル
- Decorator
- 既存のオブジェクト・インスタンスに新しい振る舞いを動的に追加
- ユースケース
- Facade
- 複数のサブシステムに対して,一つに統一されたインターフェースを提供
- ユースケース
- 数式計算
- サブシステム:数式計算ロジック用オブジェクト,計算結果出力用オブジェクト
- Flyweight
- 多数のインスタンスをキーバリュー形式で管理し,再利用
- 未管理のインスタンスを使いたい場合は,生成される
- 多数のインスタンスを管理 ⇒ Flyweight
- 1つのインスタンスを管理 ⇒ Singleton
- ユースケース
- 特殊フォント生成クラス(一文字のみ対応)による文章生成
- インスタンス:各文字の特殊フォント
- Proxy
- 共通のインターフェースを持つインスタンスを内包し,利用者からのアクセス制御と,代理
- ユースケース
- 飲食店従業員
- オブジェクト:店長,店長代理,その他従業員
振る舞いに関するパターン
- Iterator
- オブジェクトの集合に対して,順序良くアクセス
- ユースケース
- ある学校のクラス(学生オブジェクトの集合)の学生の名前を呼ぶ
- Template Method
- 抽象クラスで処理の枠組みを定義し,派生クラスでその具体的な処理を実装
- ユースケース
- コース料理:日本料理,フランス料理,,
- 処理:前菜の提供,メインディッシュの提供,デザートの提供,,
- Strategy
- アルゴリズムをカプセル化し,アルゴリズムの実装を交換可能化
- ユースケース
- お金の支払い
- アルゴリズム(支払い方法):現金,クレジット,,
- Visitor
- オブジェクトの振る舞いをオブジェクトのクラスから分離し,新しい振る舞いの追加を簡略化
- ユースケース
- 訪問者:掃除業者
- 受け入れ者:各家庭
- 各家庭は受け入れるだけ(どの掃除業者か関係ない),掃除業者は各家庭に応じて振る舞い(掃除方法)が変化する
- Chain of Resposibility
- 要求を受け取るオブジェクトの連鎖を形成
- ユースケース
- 企業
- 平社員 ⇒ 課長 ⇒ 役員 ⇒ 社長という連鎖を形成し,自分が処理できない仕事は次の役職に渡される
- Mediator
- 仲裁人を立て,オブジェクト間が直接互いに参照しない形でのオブジェクト間の相互作用を実現
- ユースケース
- 仲裁人:企業受付
- オブジェクト:社員,企業訪問者,,
- Observer
- オブジェクトの状態を観察
- ユースケース
- 観察者:先生
- 観察される側・観察者に状態を通知:学生
- 学生がある講義の出席や課題の進捗状況を報告
- Memento
- ある時のインスタンスの状態を保存し,必要な時に復元
- ユースケース
- 同じ計算式を複数回重ねて計算するときに,途中の状態を保存しておき,後からその状態を確認できるようにする
- State
- オブジェクトの内部状態の変化に伴って,オブジェクトの振る舞いも変更
- ユースケース
- オブジェクト:人
- 内部状態:感情の喜怒哀楽
- 振る舞い:言葉遣い,行動
- Command
- 命令を呼び出すオブジェクトと命令を実行するオブジェクトの分離
- ユースケース
- 家事ロボット
- 命令:掃除,洗濯,,
- 命令を呼び出すオブジェクト:リモコン
- 命令を実行するオブジェクト:ロボット
- Interpreter
- 特定言語の文法表現と,それを使用して分を解釈するインタープリタを定義
- ユースケース
まとめ
オブジェクト指向プログラミングにおいて利用されるデザインパターンについて,ざっくりとまとめた.各デザインパターンについて調べる中で,自分が思ったことを自分なりにまとめてみた内容のため,誤りが含まれていると思う.
本記事は特に自分がこれまで意識してこなかった部分でもあるため,誤解している可能性が大いにある.今後,その誤りに気づき次第,本記事と自分の認識をアップデートしていきたい.
参考文献
本記事では,GoFのデザインパターンついて,特に自分が勉強中気になった点を中心にざっくりと書いてみた.
以上でオブジェクト指向シリーズは一旦幕引きとなる(気が向いたら追加するかも).
未熟な私の記事をここまで読んでくださりありがとうございました.
お互いオブジェクト指向プログラミングについて語れるように頑張りましょう!!