IT系の方なら「増補改訂版 Java言語で学ぶデザインパターン入門」という本を見かけた事がある人も多いのではないでしょうか。
良書と推薦される機会の多い本書ですが、その分厚さから読むのを避けていた人も多いと思います。
私もその1人だったのですが、SEとして1つレベルを上げたかったため、本書を読む事にしました。
折角読んだので、自身の復習を兼ねて、本書を紹介させて頂きます。
- 全体的な感想、本書を読むメリット
- 本書の要点を紹介
- 第1章 Iterator
- 第2章 Adapterパターン
- 第3章 Template Methodパターン
- 第4章 Factory Method
- 第5章 Singleton
- 第6章 Prototype
- 第7章 Bilder
- 第8章 Abstract Factory
- 第9章 Bridge
- 第10章 Strategy
- 第11章 Composite
- 第12章 Decorator
- 第13章 Visitro
- 第14章 Chain of Responsibility
- 第15章 Facade
- 第16章 Mediator
- 第17章 Observer
- 第18章 Memento
- 第19章 Stateパターン
- 第20章 Flyweight
- 第21章 Proxyパターン
- 第22章 Commandパターン
- 第23章 Interpreterパターン
- おわりに
全体的な感想、本書を読むメリット
私はSEとして働いており、仕事でC++を使用しています。
ソフトウエアの設計時には、クラスの設計も行ってはいますが、設計は勘や慣れに頼る事が主でした。
本書は「Java」とタイトルにありますが、C++とJavaは似たような言語であるため、C++しか分からない人でも内容理解に問題はありません。
そんな私が本書を読んで得られた気づきは以下の2つです。
- 感覚でクラス設計をしてもオブジェクト指向にはなり得ない
- デザインパターンを使ったコードは、読む人に設計思想が伝わりやすい
感覚でクラス設計をしてもオブジェクト指向にはなり得ない
オブジェクト指向は分かった様で分からない物の1つだと思います。
私のこれまでの理解では、機能を適切に分けてやれば部品としての利用価値の高いクラスができ、再利用もし易くなるという事でした。
ただ、この理解はオブジェクト指向の浅い理解でした。
再利用性や、機能を追加し易くするには、継承や委譲などを上手く使うのが効果的で、上手く使うために効果的なのがデザインパターンを利用する事です。
感覚で設計するだけでは、オブジェクト指向とは言い難く、オブジェクト指向とデザインパターンはセットで扱う物だと考えます。
デザインパターンを使ったコードは、読む人に設計思想が伝わりやすい
クラスを使用して設計すると、継承関係が複雑になったりして、コードを読みにくくなる事があります。
コードを読む際に、どのデザインパターンが使われているかが分かれば、読む方も設計思想を汲み取る事ができ、構造を掴み易くなります。
また、設計者とは別の人が改修する事になっても、デザインパターンが伝われば、部品としての価値を落さずに改修する事が容易になります。
ソースコードは、書くのではなく、読まれる事の方が多い物です。
つまりは、可読性の高いコードを書けることは腕の良いエンジニアの条件の1つです。
オブジェクト指向には共通となる思想がある
多くのデザインパターンに共通するのが、インタフェース(枠)となるクラスと、具体的な実装を行うクラスに分ける事です。
設計する際には、どのデザインパターンを使用し、インタフェースと具体的な実装の区分けをどうするかを考える事が必要になります。
本書には各デザインパターンのサンプルコードも紹介されているため、インタフェースと具体的な実装の区分けを具体的に理解する事ができます。
その他:この1冊を読めばソース読解のレベルが1つ上がる
本書では、各デザインパターン毎にサンプルコードが用意されています。
デザインパターン自体、継承等を多用するため、初心者が読むには少し難易度が高いかもしれません。
ですが、本書を一通り読めば、ソースを読む際に手こずりがちな継承にも慣れる事ができるため、実務でソースを読む能力も上がります。(実際に私がそう感じました。)
デザインパターンを知る事で、再利用性の高い部品を作れたり、コードを読むスピードも上がるので、開発効率を高めたいなら押さえておくべきスキルです!
本書の要点を紹介
デザインパターンとは、GoF(Gang of Four)と呼ばれる4人が定めた23の設計パターンのことです。
本書は、この23個の設計パターンについて、サンプルコードと筆者による解説が掲載されています。
23個のデザインパターンの種類と、その概要を以下にまとめました。
第1章 Iterator
- 複数の要素を順番にスキャンしていくためのデザインパターン
- Iteratorパターンを使用する事で、クラス間の結合を弱めて部品としての再利用性を高めることができる
第2章 Adapterパターン
- Adapterパターンは「既にある部品」と「使いたい部品」との間にあるずれを埋めるためのデザインパターン
- Adapter(アダプター)を使い、既にある部品を包む様にする事で、既にある部品に手を加える事無く利用できる
第3章 Template Methodパターン
- 共通的な処理のアルゴリズムをテンプレートとして抽象メソッドにしておけば、複数の具象クラスを作成した場合に、後でアルゴリズムを変更する際に抽象クラスの変更だけで済ませる事ができる
- 抽象クラスに多くの処理が実装されていると、共通部分は増えるが、具象クラスの自由度が減るというトレードオフがある
第4章 Factory Method
- Factory MethodパターンはTemplate Methodパターンの応用形で、スパークラス側に複数のクラスやインタフェースを用いるデザインパターンである
- インスタンス生成のフレームワーク側、実体のインスタンスを生成する側の2つに分ける事で、同じフレームワークを複数の種類の実態に対応付ける事ができる
第5章 Singleton
- Singletonパターンは、指定したクラスのインスタンスが絶対に1つしか存在させないためのデザインパターンである
- コンピューターそのものの状態など、1つしか存在しては困るクラスに使用される
第6章 Prototype
- Prototypeパターンは、newによりインスタンスを作成するのではなく、インスタンスから別のインスタンスを作成するデザインパターンである
- Prototypeパターンは以下のような場合の解決策として用いられる
- 扱うオブジェクトの種類が多すぎて、クラスにまとめられない場合
- 複雑な過程を経てデータが操作されているインスタンスをいったん保存しておきたい場合
- インスタンスを生成するときのフレームワークを、特定のクラスに依存しないようにしたい場合
第7章 Bilder
- Bilderパターンとは、構造物(building)を次々と建築していくように、構造を持ったインスタンス(複数の手続きを踏むインスタンス)を複数生成するためのデザインパターンである
- 共通的に使用するインタフェースを定義し、それを継承したクラスに具体的な機能を持たせるが、使用側はなるべく共通インタフェースのみを使用する事で、複数の種類のインスタンスを生成する事ができる
第8章 Abstract Factory
- Abstract Factoryパターンとは、具体的な実装は持たない抽象的な工場・部品・製品インタフェースを用い、複数の具体的な工場を実装するのに役立つデザインパターンである
(作成したいデータの加工役を工場に見立て、工場で部品を作成、組み合わせて製品を作成するイメージ)
第9章 Bridge
- Bridgeパターンとは、クラスをインタフェースを提供するだけの機能のクラス階層と、具体的な実装のクラス階層の2つに分けて設計するデザインパターンである
- クラスを機能のクラス階層と実装のクラス階層に分け、それぞれの役割をはっきりさせる事で、部品として価値の高いクラスを作りやすくなる
第10章 Strategy
- Strategyパターンとは、アルゴリズムを1つの部品とし、その部品を他の部品と容易に切り替えるためのデザインパターンである
- アルゴリズムを、共通的なStrategy(戦略)インタフェースと、個別の戦略であるConcreteStrategy(具体的戦略)クラスとに分け、引数等で同じインタフェースから各具体的戦略のクラスを呼び出す
第11章 Composite
- CompositeパターンのCompositeとは「混合物」「複合物」の意味で、入れ子構造(再帰的な構造)を表現するのに適したデザインパターンである
- 入れ子構造の中身と、入れ子構造の箱側を 共通のインタフェースを継承させる事で実現する
第12章 Decorator
- Decoratorパターンとは、デコレーションケーキの様にスポンジケーキ(中心となるオブジェクト)に、デコレーション(飾りつけ)をしていく様な設計に使えるデザインパターンである
- Decoratorパターンでは、中心のオブジェクトと飾りつけのクラスには同じインタフェースを持たせ(透過的なインタフェースにし)、飾りつけのクラス内に機能を実装しておくことで、インタフェースは変えずに機能を実装する事ができる
第13章 Visitro
- Visitorパターンとは、データ構造と処理を分離し、処理を訪問者(visitor)に見立て、色々なデータ構造を訪問していくデザインパターンである
- 例えば、データ構造として、ディレクトリ構造を保持するクラス、ファイルリストを保持するクラスを作成し、訪問者として一覧を表示するクラスを作成します。訪問者がディレクトリ構造を保持するクラスを訪問すれば、ディレクトリの一覧を表示し、ファイルリストを保持するクラスを訪問すれば、ファイルの一覧を表示する、といった具合である
- データ構造と処理を分離する事で、独立性が高まるので新しい機能の追加が容易になる
第14章 Chain of Responsibility
- Chain of Responsibilityとは、たらい回しという意味で、ある処理を実行するオブジェクトが簡単には特定できない場合に、複数のオブジェクトをたらい回しにし、適当なオブジェクトを見つけるためのデザインパターンである
- ある処理の要求に対しどのオブジェクトがその要求を処理するかをメイン関数等で制御すると、制御側のクラスが複雑になってしまうが、Chain of Responsibilityパターンを使用すれば、制御側はたらいまわしの先頭に要求を投げればよく(あとはたらい回しクラスが内部で宜しく処理してくれるので)、制御側の処理を単純にする事ができる
第15章 Facade
- Facade(窓口)パターンは、大きなプログラムになると、どうしてもクラス間・メソッド間の関係が複雑になるため、それらをまとめたシンプルなインタフェースを提供するためのデザインパターンである
- シンプルなインタフェースにする事で、オブジェクトの呼び出し順の誤り、意図しない使われ方を防ぐ事ができ、外部とのインタフェースを疎にする事で、独立性がたかまり部品としての再利用性を高める事ができる
第16章 Mediator
- Mediator(調停者)パターンとは、複数のオブジェクトが互いの状態に影響を受け合う様な場合に、オブジェクト間の関係が複雑になってしまうのを防ぎ、簡略化するためのデザインパターンである
- 簡略化のために、調停者役のクラスを用意し、各オブジェクトは調停者役とだけやりとりする様にする事で、通信経路を減らし、また、調停者役以外のオブジェクトの独立性を高める事ができる
第17章 Observer
- Observer(観察者)パターンとは、観察対象のオブジェクトの状態が変化した際に、状態に応じた処理を行うためのデザインパターンである
- 観察する側と、観察される側を抽象クラスのインタフェースを介して繋げる事で、状態に応じた処理を行う実装クラスを容易に交換する事ができる
第18章 Memento
- Memento(記念品)パターンとは、ある時点のインスタンスの状態(変数等)を保管しておき、いつでもその時点に戻せる様にする際の(テキストエディタのundo機能を使う様な)デザインパターンである
- 保管対象のオブジェクトに対して外部から自由にアクセスできると、クラスとしての独立性が下がるという問題がある
- Mementパターンでは、publicとするインタフェースをできるだけ少なくし内部の状態を隠す事で、あるタイミングのオブジェクトをひと固まりのモノとして扱わせる
第19章 Stateパターン
- Stateパターンとは、クラスの対象として“モノ”ではなく、“状態”を対象として扱うデザインパターンである
- 状態をクラスとして扱う事で、各状態のクラスを設計する際に、その状態の事だけを意識すればよくなる(ex.Aという状態の場合は、xとyの処理をする、といった具合で、これが逆だと、状態が多い場合には、xの処理を行うのは、A,B,C,D,Hの場合といった様な分岐が発生し、複雑になってしまう)
第20章 Flyweight
- Flyweight(軽量)パターンとは、多くのインスタンスを生成する際に、同一のものがある場合はメモリを共有する事で、全体のメモリ使用量を削減するデザインパターンである
- メモリを共有させる設計になるため、共有部分が多くなるほど、メモリの削減量は大きくなるが、変更が難しくなるという問題もある
第21章 Proxyパターン
- Proxy(代理人)パターンとは、ある機能を代理するためのオブジェクトを作成し、その機能が本当に必要になるまでは、代理役を務めさせるというデザインパターンである
- 初期化に非常に時間がかかるクラスに対し、初期化を簡略化した代理人クラスを作成しておき、なるべく代理人で処理することで、処理の軽量化を図る事ができる
第22章 Commandパターン
- Command(命令)パターンとは、1つのメソッドに1機能という考えではなく、1クラスのインスタンス自体を1つの機能としてコマンドの様に扱うデザインパターンである
- 同じ命令を何度も実行したり、複数の命令をまとめたり、クラス内に履歴を保存する機能を持たせておけば、コマンドの履歴を残す事もできる
第23章 Interpreterパターン
- Interpreter(通訳)パターンとは、ミニ言語(動作させているプログラミン言語とは異なる言語で、インタラクティブな言語)で書かれたプログラムを、構文解析し、実行するためのデザインパターンである
- (本書の場合は)Java言語で、メイン側の処理を書いておき、機能的ば部分はミニ言語化しておけば、機能を変更してもメイン側は変更しなくてもよいというメリットがある
おわりに
なかなか読み応えのある本でしたが、オブジェクト指向について勉強したい人なら、読んでおいて損はありません。
ただし、分厚い本であり挫折する可能性も高いので、SEとして本気でレベルを上げたいと考えている人以外は、購入をお勧めしません。
オブジェクト指向に関しては以下の記事もご参考にどうぞ。
ご参考になりましたら幸いです。
以上
コメント