デザインパターン
デザインパターンとは
過去のソフトウェア設計者が発見し編み出した設計ノウハウを蓄積し、名前をつけ、再利用しやすいように特定の規約に従ってカタログ化したもの 1994 年に出版されたものであり多くのパターンは古く現代のプログラミングとマッチしないとも言われている。
それぞれのパターンについて
23 種類のパターンがある。
1-1 iterator
iterator とは何かが集まっているときに一つ一つを順番に指し示していき全体をスキャンしていく処理を一般化したもの
aggregate インターフェース 数え上げを行うものの集合体
具体的なクラスだけで実装しようとするとクラス間の結合が強くなってしまい再利用性が薄れるため抽象クラスやインターフェースを使うということを頭に入れておく。
1-2 Adapter
2つのパターン
- クラスによる adapter パターン(継承を使ったもの)
- インスタンスによる adapter パターン(委譲を使ったもの)
委譲とはあるメソッドの実際の処理を他のインスタンスに任せてしまうこと
既存のクラスを使って機能を実装したい時に使える 既存のクラスに一皮被せて必要とするクラスを作る バグが発生した際は adapter 役のクラスを調べるだけでいいのでチェックが楽になる
1-3 Template Method パターン
スーパークラスで処理の枠組みを定めサブクラスで具体的な内容を実装するパターンのこと
- ロジックが共通化できる
- スーパークラスのテンプレートメソッドでアルゴリズムが記述されているためサブクラスで記述する必要がない
- 結果、バグが起きた際に concrete メソッドをテストせず abstract メソッドをテストするだけで良くなる
- 継承の一般的な原則
スーパークラス型の変数にサブクラスのどのインスタンスを代入しても、正しく動作するようにするという原則を The Liskov Substitution Princple(LSP)と言う。
1-4 Factory Method パターン
インスタンスの作り方をスーパークラスで定める
具体的なクラス名、肉付けはサブクラスで行う
framework class
Product class 製品は何はともあれ使える
Factory class 製品を創り登録する 具体的な製品を知らないが創るための method と product についてのみ知っている
concrete class
IDCard class product の subclass owner 情報を持つ、使う具体的な処理を実装、owner 情報を返せる
IDCardFactory class factory の subclass create_product と register_product の具体的な実装 owners list を持ち、返せる
この構造のおかげで具体的な product のクラス名から Factory class は解放される
コラム(抽象クラス、インターフェースについて)
抽象クラスとは何か
まさにその名の通り、抽象化されたクラスを指す言葉。抽象化とは、例えば、人間/犬/猫を抽象化する場合には「動物」となるような、共通した項目(簡潔な項目)に置き換えることである。
人間クラス/犬クラス/猫クラスが存在する場合、これらは動物クラスを継承して作ることができる、と考えると分かりやすい。
つまり、人間クラス/犬クラス/猫クラスを構成するのに必要な最低限の実装が動物クラスには含まれており、これを継承(extends)して内部のメソッドをオーバーライドすることで動物としての共通した機能を持たせつつ、種族によって独自の機能を持った人間クラス/犬クラス/猫クラスを作れるのである。
抽象クラスのルール
- 抽象クラスのオブジェクト(抽象クラスのインスタンス)を生成することはできない
- 抽象メソッドが存在するクラスは必ず抽象クラスとして宣言しなければならない
- 抽象クラスには通常のメソッドを記述することもできる
- 抽象メソッドがない抽象クラスを作ることもできる
- 「抽象メソッドが存在する抽象クラス」を継承したサブクラスでは抽象メソッドをオーバーライドしなければならない
- 抽象クラスやクラスを多重継承(一度に複数個を継承)することは出来ない
インターフェースとは何か
インターフェースについて説明する為にはカプセル化という考え方を知っておく必要がある。
カプセル化とは「クラス内部の複雑な実装を見なくても、手続きさえ知っていれば外部からクラスを扱えるようにしよう」という考え方のこと。
インターフェースはカプセル化の為に用意されたものである。何故かというと、インターフェースさえ見ればクラス内部の実装を見なくてもクラスを扱うことができるからだ。
インターフェース内部に記述されたメソッドは、インターフェースを使用しているクラス内部でオーバーライドして実装されることが約束されている。 もし、実装されていなかった場合はコンパイルエラーとなる。
インターフェースのルール
- インターフェース内では、変数及び、メソッドの宣言のみ行うことが出来る
- インターフェースのオブジェクト(インターフェースのインスタンス)を生成することは出来ない
- インターフェースを実装(implements)したクラスはインターフェース側で宣言されているメソッドを実装しなければならない
- インターフェース内で定義した変数は、定数になり、変更することができない
- Java はクラスの多重継承を許可しておらず(菱型継承問題のため)、単一継承のみ許可しているが、インターフェース同士での多重継承は許可している