カプセル化と情報隠蔽は非常に密接に関連した概念ですが、正確な定義は話し相手によって異なります。
「情報隠蔽」の概念は、システムの相互接続性を減らすために情報へのアクセスを制限する必要があることを示唆したParnas(1972)によって最初に説明されました。彼は、これにより、ユーザーフレンドリーな外部インターフェイスを維持し、クライアントに影響を与えることなく実装の詳細を変更できるようにしながら、システムをモジュールに分割することが容易になると提案しました。
「カプセル化」という用語は、システムの複雑さを軽減し、危険な変更からデータを保護するために、基礎となるデータへのアクセスを制御する手順の使用を説明するためにZilles(1973)によって造られました。
その後、Parnas(1978)は、情報の隠蔽とカプセル化(および抽象化)を同義語として説明しました。これは、変更される可能性のあるシステムの詳細の隠蔽を説明しています。ただし、カプセル化を「情報隠蔽の厳格な実施」と説明したMicallef(1987)のように、情報隠蔽とカプセル化の間には区別があります。Cohen(1984)やAbreu and Melo(1996)などの一部の著者は、特にオブジェクト指向プログラミング言語での「カプセル化メカニズム」を、情報の隠蔽を可能にするものとして説明しています。
Meyers(2000)は、コードの一部がカプセル化される程度は、変更された場合に破損するコードの量に依存することを示唆しています。この意味で、プライベートデータとメソッドは、アクセスできるメソッドが少ないほど、よりカプセル化されます。対照的に、パブリックデータとメソッドは、アクセスできるコードの量が不明であるため、完全にカプセル化されていません。
逆に、Rogers(2001)は、カプセル化は、データをそのデータを操作するメソッドにバンドルできるようにする言語メカニズムにすぎないと示唆しています。彼は、カプセル化は基本的に情報隠蔽とは何の関係もないと主張しています。ただし、この定義は、彼の記事が公開される前の28年間の学術文献でのこの用語のほとんどすべての使用法に反しています。この使用法の例は他にもいくつかあります。たとえば、Archer and Stinson(1995)ですが、それらはごくわずかであり、特に注目に値するものではありません。
結論として、情報隠蔽とは、クライアントに影響を与えることなく設計を変更できるように、情報を隠蔽する必要があるという考えです。これにより、柔軟性と安全性が向上します。カプセル化は情報隠蔽と同じと見なすことができますが、この用語は、特にオブジェクト指向プログラミングにおける情報隠蔽の実際の実装を説明するためによく使用されます。
情報の隠蔽/カプセル化の例として、次のクラスを検討してください。
public class BankAccount {
public int dollars;
}
このクラスの実装は完全にカプセル化されていません。つまり、柔軟性がなく(たとえば、将来的に個々のセントのサポートを簡単に追加できない)、安全ではありません(たとえば、アカウントがマイナスに変更される可能性があります)。ただし、正式に定義されたメソッドのインターフェイスの背後にデータを隠すと、柔軟性と安全性が得られます。
public class BankAccount {
private int dollars;
public void deposit(int dollars) {
this.dollars += Math.max(0, dollars);
}
}
これで、状態の変更方法を制御できるようになりました。また、クライアントコードを壊すことなく、実装を変更することもできます。
public class BankAccount {
private int cents;
public void deposit(int dollars) {
deposit(dollars, 0);
}
public void deposit(int dollars, int cents) {
this.cents += Math.max(0, 100 * dollars) + Math.max(0, cents);
}
}
基礎となる実装に関する情報が隠されているため、クラスはより適切にカプセル化されています。