ソフトウェアの構成要素(クラス、モジュール、関数など)は拡張に対して開いていて、修正に対して閉じていなければならない
- 「硬い」設計をしてしまうと、プログラムのちょっとした変更でさえ、その箇所と依存関係を持つ全てのモジュールに影響を与えてしまう
- OCPはあとで似たような変更もっと出てきたときにコードを修正しないで済ませるにはどうすれば良いのかを教えてくれる
- OCPをうまく適用してシステムをリファクタリングできれば既に動いている既存のコードには一切修正を加える必要がない
オープン・クローズドの原則(OCP)の概要
オープン・クローズドの原則(OCP)に従って設計されたモジュールには次のような特徴的な2つの属性がある
- 1. 拡張に対して開かれている(オープン: Open)
- これはモジュールの振る舞いを拡張できるという意味である。アプリケーションの仕様要求が変更されてもモジュールに新たな振る舞いを追加することでその変更に対処できる。つまり、そのモジュールの処理内容を変更できる。
- 2. 修正に対して閉じている(クローズド: Closed)
- モジュールの振る舞いを拡張してもそのモジュールのソースコードやバイナリコードは全く影響を受けない。既にモジュールがコンパイルされてバイナリ形式になっているものはDLLであろうとJavaの.jarファイルであろうと手を触れる必要はない。
- この2つの属性は一見矛盾しているように思える
- モジュールの振る舞いを拡張するにはそのモジュールのソースコード自体を変更しなければならない
- また、ソースコードを変更できなければそのモジュールの振る舞いを変更することはできないと思うのが普通
鍵は「抽象」にあり
- C++やJavaなどのオブジェクト指向言語では宣言が固定されていても、それが特定の実装に結合していないメソッドを「抽象」を使って表現できる
- これらの言語では「抽象」は抽象基本クラスを使って記述され、特定の実装に結合していないメソッドはその派生クラスで実装される
- モジュールの設計では、こういった「抽象」のメカニズムを巧みに利用できる
- モジュールをある固定した「抽象」に従属させておけば修正に対してコードを閉じることができる
- なぜなら「抽象」を使えばコードを修正しなくても、その「抽象」の派生クラスを新たに追加するだけでモジュールの振る舞いを拡張できるからである
まとめ
- いろいろな意味でオープン・クローズドの原則(OCP)はオブジェクト指向設計の核心である
- この原則に従うことでオブジェクト指向技術から得られる最大の利益(柔軟性、再利用性、保守性)を享受できる
- しかしオブジェクト指向のプログラミング言語を使えば自動的にOCPに準拠できるわけではない
- アプリケーションのあらゆる部分で抽象を無闇に使えばいいわけでもない
- 開発者が担当する部分で最も頻繁に変更されるプログラム部分にだけ的を絞って抽象を適用するように務めるべきである
- 早まった「抽象」をしないことも「抽象」を使うのと同等に重要なことである