ここでは,オブジェクト指向に出てくる法則・原則をまとめました.パターンに比べてほとんど知られていないのが現状ですが,優れたオブジェクト指向開発者を目指すならデザインパターンよりまずこっちを理解し覚えてしまいましょう.
これらの法則は,絶対守らなければならないというものではありません.開発中に法則が守られているか意識することが重要です.つまり
と絶えず考えるようにしましょう.そうするとそれは自然に優れたオブジェクト指向設計になるのです.つまりこれらの法則は,優れたオブジェクト指向開発のための指針なのです.
Robert C. Martinは,オブジェクト指向設計の指針になる法則集を`Principles of OOD'の形でまとめています.以下は彼のC++ Report連載記事から引用しました.Object MenterからPrinciples of OOD関連のアーティクルはすべて入手できます.
Bertrand Meyer先生の有名なOCPです.OOSCの訳本では,「開放/閉鎖原則」となっていますが,難しそうなので個人的に「むすんでひらいての法則」と命名(^^;.僕の考えでは,オブジェクト指向が先にきて次にOCPが来るのではなく,OCPがまずあってそれを実現するための手段としてオブジェクト指向がくると考えます.これとデザインパターンとの関連についての詳しい記事はこちらです.本当はOCPを広めるためにこの記事を書いたのですが,やはり雑誌の売れ行きを考えるとパターンをからめないといけなかったのです(苦笑).
LSPは継承使う場合常に意識した方がよい重要な原則です.これを知らずして継承を使うべからず,といったところでしょう.なぜオブジェクト指向の入門書にこいつを書かないのかいまだに不思議です.LSPはMeyer先生のDesign by Contractでもうちょっと厳密に表せます.
オブジェクト指向では構造化プログラミングに対して依存関係が逆転してしまう,という法則です.オブジェクト指向で一番面白いところですね.今はどうか知りませんが,昔はCでごりごりプログラムを書いてきた人ほどオブジェクト指向に移行するのが難しいといわれました.その原因がこの逆転の発想なんでしょう.このことを踏まえて「依存関係のコペルニクス的転回」と勝手に命名したこともあります(笑).
インターフェイスを分離せよ,インターフェイスを太らせてはいけない,ということです.静的型づけ言語の場合,これを実現するには Java の interface か C++ の多重継承がどうしても必要になります.意図は違いますが,Adapterパターンに似ていますね.Adapterパターンの場合は,他のオブジェクトとお話ができるようにインターフェイスを変換しよう,ということですが,この法則が言っているのは,お話するのに必要最小限のインターフェイスしか教えないようにしよう,ということです.
ここからは,個々のクラスではなく,クラスを集めたパッケージに関する原則になります.この REP は,パッケージを再利用可能にするためのシステムについて述べたものです.一般に,クラス単体は再利用可能ではありません.あるクラスは他のクラスに依存している場合がほとんどです.再利用可能にするには,クラス群をリリースする単位としてパッケージ化し,バージョン管理を行うようにすべきだ,ということです.そういうシステムがない限り,再利用はうまくいかない,ということでしょう.
パッケージに入れるクラスは何にするかという判定基準を再利用の観点から表したものです.あるパッケージをバージョンアップする場合,利用している側のソフトウェアにとって関係のないクラスが修正されたにも関わらず更新しなければならない,というのはおかしな話です.パッケージをリリースしたあとの配布の問題を考えてもこうなっていることが理想です.Interface Segregation Principle のパッケージ版といえますね.
今度は,パッケージに入れるクラスは何にするかという判定基準をメンテナンス性から表したものです.ソフトウェアを修正しなければならない場合,その修正があるパッケージの中で閉じているにこしたことはありません.だから,将来起こるであろう変更を想定した場合,いっしょに修正することになるクラスは同じパッケージに入れてしまったほうがよい,ということです.
ここから先は,パッケージ間の依存関係についての原則になります.ADP は,依存関係が循環してはいけない,ということを述べています.パッケージの依存関係がどこかで循環していると,それらのパッケージを単独でアップデートすることはできません.アップデートするとしたら,循環しているパッケージ全体を一度に行わなければならないのです.この原則は,必ず守らなければならないものといってよいでしょう.
ここではStability(安定性)という用語が出てきます.Robert C. Martinのいう安定性とは,「変更する難易度」とでもいうべきものです.安定しているパッケージは修正が難しく,不安定なパッケージは修正が容易,ということですね(なんか変な感じ).SDP は,パッケージの依存関係はより安定しているパッケージへと向かうべき,ということです.
今度はStabilityとAbstractionの関係です.パッケージの依存関係は抽象度が高いパッケージへの向かうべき,でしょうか.SAP と SDP は Dependency Inversion Principleのパッケージ版です.Robert C. Martin は,パッケージからこの安定性と抽象度を数値的に測定し,Main Sequence というアイデアを導入しています.このMain Sequenceの考え方にはとても感動しました.ぜひ彼の本または記事を読みましょう.
デメテルの法則の定義は,Brad Appletonの記事(Introducing Demeter and its Laws)から引用しました.オブジェクトは直接の友達以外お話しちゃだめ,というルール.友達の友達にまでアクセスすると,友達が勝手にそいつと縁を切った場合困る,ということでしょうね.このルールに厳密に従うにはラッパーを作らないといけないのでかなり面倒だと思います^^;.ほどほどがいいんじゃないでしょうか.