kyosho5’s blog

貧乏で数学があまり得意ではない理系出身のエンジニアのブログ

デザインパターン勉強メモ②

第3章 Template Methodパターン

スーパークラスにテンプレートとなるメソッドを定義し、その中で抽象メソッドを使った処理を実装する。
スーパークラスでは抽象メソッドの呼び出しによって処理の流れだけを記述し、具体的な処理内容はサブクラスにて実装する。

・Abstractクラス
→テンプレートメソッドを実装する。その中では使用する抽象メソッドを宣言する。
抽象メソッドの実装はConcreteクラス(サブクラス)で行われる。

・Concreteクラス
→抽象メソッドを具体的に実装する。Abstractクラスのテンプレートメソッドより呼び出される。

ロジックの共通化ができる。
サブクラスの実装を行うときは、スーパークラス内でどのような処理の流れになっているかを理解する必要がある。
スーパークラス型の変数にサブクラス型のインスタンスを代入する方式にする時に
instancofなどでサブクラスの種類を特定せずにプログラムが動くようにする方針が良い。
スーパークラス型の変数にサブクラスのインスタンスのどれを代入しても正しく動作するようにするという原則を
リスコフの置換原則(LSP:The Liskov Substitution Principle)という。←継承の一般原則

スーパークラスとサブクラスの実装密度のトレードオフを意識する。
スーパークラスは骨組み、サブクラスは肉付けという意識。
正解はないので設計時によく考えること。

スーパークラスは、サブクラスに対して抽象メソッドの実装を期待している
→サブクラスの責任(Subclass Responsibilities)

第4章 Factoryパターン

Template Methodパターンをインスタンス生成の場面に適用したもの。
インスタンスの作り方をスーパークラスで定めるが、具体的な肉付けは
すべてサブクラス側で行う。

・Product役
フレームワーク側。このパターンで生成されるインスタンスが持つべきインタフェース(API)を定める抽象クラス。
具体的な内容はサブクラスのConcreteProduct役が定める。

Creator
フレームワーク側。Product役を生成する抽象クラス。
具体的な内容はサブクラスのConcreteCreator役が定める。
Creator役が知っているのはProduct役とインスタンス生成のメソッドを呼び出せばProductが生成されるということのみ。
newによる実際のインスタンス生成をインスタンス生成のためのメソッド呼び出しに変えることで
具体的なクラス名による束縛からスーパークラスを解放している。

・ConcrteProduct役
→具体的な肉付けを行うクラス。製品を定める。

・ConcreteCreator役
→具体的な肉付けを行うクラス。製品を作るクラスを定める。

スーパークラス(抽象的な骨組み・フレームワーク)側にあるCreator役とProduct役の関係が、
サブクラス(具体的な肉付けの側にあるConcreteCreator役とConcreteProduct役の関係と並行している。

サンプルソースでは、frameworkパッケージの中ではidcardパッケージをインポートしていない
→ProductクラスやFactoryクラスの中では具体的なクラス名が書かれていない
→新しいクラスを同じフレームワークで生成する場合もframeworkパッケージを変更する必要がない
「frameworkパッケージはidcardパッケージに依存していない」


デザインパターンを使ってクラス群を設計する場合、そのクラス群を保守する人に
設計者の意図が何であるのかがうまく伝わるようにする必要がある(意図せぬ修正をされないように)
コメントやドキュメントの中で実際に使われているデザインパターンの名称や意図を記述しておくのがよい。

クラスやインタフェースの相互関係に目を向けること。

ここまでの感想

4章あたりからは具体的なコードだけを頼りにするのではなく、より抽象的に各クラスやインタフェースの関係をイメージできるようにする必要があると感じた。
若干、腑に落ちる前に頭の中を通過していってしまっている感があるので、明日もう一度5~10分程度時間をとって読み返してみることにする。