カプセル化
オブジェクト指向以前の定義(後続の書籍からよく参照される)。
モジュールを分解する際に最も重要な基準は、モジュールがシステムの他の部分から隠すべき秘密を特定すること
『On the Criteria To Be Used in Decomposing Systems into Modules 』D.L. Parnas (1972)
ただここでは、Ensapsulationという用語は使われておらず、「Information hidding (情報の隠蔽)」である。
書籍での定義
Effective Java
よく設計されたコンポーネントとそうでないコンポーネントを区別する最も重要な要素は、そのコンポーネントが他のコンポーネントから内部データやその他の実装の詳細をどの程度隠しているかということだ。よく設計されたコンポーネントは、その実装の詳細をすべて隠し、APIと実装をきれいに分離します。そして、コンポーネントはAPIを通じてのみ通信を行い、お互いの内部動作には気づかない。
Design Patterns
オブジェクトの中にデータと実装を隠した結果。データは目に見えず、オブジェクトの外部から直接アクセスできない。操作は、オブジェクトのデータにアクセスし、変更する唯一の方法である。
Domain Driven Design
オブジェクトは手続きをカプセル化するものであり、その代わりにその目的や意図について考えさせるものである。
Clean Architecture
データと関数をひとまとまりにし線で囲む。線の外側ではデータは隠され、関数の一部だけが知られている。
Clean Architectureではこれはオブジェクト指向の専売特許ではなく、Cでは完璧なカプセル化が実現されていた。と、以下の例を挙げている。
code:point.h
struct Point;
struct Point* makePoint(double x, double y);
double distance (struct Point *p1, struct Point *p2);
code:point.c
struct Point {
double x,y;
};
struct Point* makepoint(double x, double y) {
struct Point* p = malloc(sizeof(struct Point));
p->x = x;
p->y = y;
return p;
}
double distance(struct Point* p1, struct Point* p2) {
double dx = p1->x - p2->x;
double dy = p1->y - p2->y;
return sqrt(dx*dx+dy*dy);
}
考察
情報の隠蔽を目的とした一手段がカプセル化であり、隠したい情報は、
1. 実装の詳細
2. 内部のデータ表現
と言える。
オブジェクト指向はこれを実現するために、データに可視性を設けて直接触れないようにすることを推奨した結果、データと振る舞いをセットにする必要が出てきた。
さらには、これだけでは1の実装の詳細を隠蔽できるかは設計による。実装の詳細の隠蔽に言及しているのはDomain Driven Designであるが、目的と意図について考えれるようにするためには、優れた名前とインタフェースが必要となる。