検索
オブジェクト指向において、カプセル化は要です。クラスを作成する際に非常に重要な要素です。
(カプセル化されていないクラスは、配線や可動部が剥き出しの機械と同じくらい危険です...)
カプセル化を考える際のポイント
「クラスを作る=同時にカプセル化」を常日ごろ心がけましょう。
1つ例をあげます。正の数を保持するだけのクラスです。保持している値は変えられません。マイナスの場合は0を保持します。
下はカプセル化されていないクラスです。
(1)
1|//正の数クラス 2|public class PositiveNumber 3|{ 4| public int Value = 0; 5| 6| public PositiveNumber(int value){ 7| this.Value = this.DataHosei(value); 8| } 9| 10| public int DataHosei(int value){ 11| if(value < 0){ 12| return 0; 13| } 14| 15| return value; 16| } 17|}
たったこれだけのソースコードですが、ソースを見ていても何がしたいのか、何のクラスなのかわからないですねー。
このクラスを公開すると、次のような使われ方をされるでしょう。
(2)
1|//正の数クラスを使うクラス 2|public class Sample 3|{ 4| public Sample2(){ 5| PositiveNumber number = new PositiveNumber(-2); 6| number.Value = -10; // 値が代入できるのから入れてみた 7| Console.WriteLine(number.Value.ToString()); 8| 9| int exValue = number.DataHosei(-99); //丁度いい処理があったので使ってみた 10| } 11|}
カプセル化考慮したクラスは次のようになります。
(3)
1|//正の数クラス 2|public class PositiveNumber 3|{ 4| public int _value = 0; 5| 6| private PositiveNumber(int value){ 7| this._value = this.DataHosei(value); 8| } 9| 10| public int Value{ 11| get{ return this._value; } 12| } 13| 14| private int DataHosei(int value){ 15| if(value < 0){ 16| return 0; 17| } 18| 19| return value; 20| } 21|}
こうすることで、クラス外部から出来ることと出来ないことが明確に分かれ、クラスを見ることで何をするクラスなのかが読みとれます。
また、ソース(2)6行目の代入はできなくなり、9行目のメソッド使用もされることはなくなります。
ソース(2)9行目は呼べてもいいのではと思われるかもしれませんが、この処理の意味は
「渡された値をオブジェクトが保持する値に補正する」ことで、「マイナス値を0にする」ことではありません。
このように外部から使われてしまっては、DataHoseiの内容が変わった場合に既に「マイナス値を0にする」ことで使われているので、処理内容を変更することができません。
このように、カプセル化を怠っていると、本来の処理以外の事を気にしないといけない上に、 後での修正・カスタマイズを困難にし、昔と変わらないスパゲティープログラムと化してしまいます。 オブジェクト指向で設計を進めていくと、膨大なクラスの数になります。 1つ1つのクラスの「カプセル化」を後で見直すことは困難で現実的ではありません。そんな面倒なことはしたくありません。
1つ1つのカプセル化を確実に行い、安全で頑丈なクラスを積み重ねていきましょう。
カプセル化は要です。