カプセル化

encapsulation.png

カプセル化とは?

やり方

データメンバだけをprivateにして、関数をpublicにすること
(別にprivateな関数を定義することもok)

デザインパターンとカプセル化

デザインパターン 何をカプセル化しているか?
Adapter インタフェースの変更
Template-Method アルゴリズム

理論的観点

オブジェクトの内部状態は外から直接アクセスすることはできず、さらにその表現形態も外からは見えない仕組みになっている[1]

カプセル化の利点

Agree? 本に書かれていた利点 反論
X クライアントは、クラスを使う時に、()をつけるんだっけかどうか、考えなくてすむ。(常に()をつける) 今どきのIDEは必ず綺麗シンタックスハイライトしてくれるし、コードの自動補完もある。
だから、変数だっけ関数だっけなんでそもそも考える必要ない。時代遅れ
X データメンバのアクセスを精密に制御できる(readOnlyとかwriteOnlyとか) readOnlyにしたいならconstをつければいい。writeOnlyで、読むの禁止とか普通ある??
? クラスを作る側にしてみれば、こっそりデータメンバの内容、名前、数を変えてもクライアントにはわからない。 クライアントにはわからなくて、何が嬉しい???
O ある変数がいつ、どのようにアクセスされたかを追跡しやすくする

3番めの利点は、クラスを目的に応じて柔軟に作れるということ。
どれも、チームでプログラミングする時にだけ見えてくる利点だ。他の利点はないのか?

欠点

  • いちいちgetとsetをつけなきゃならなくて面倒くさい。コードが増える。

カプセル化すべきもの

インタフェースを作って
実行速度重視のクラスを派生させたり、
データサイズが小さくて済むことを重視したクラスを派生させたり、
目的に応じて柔軟に対応できる。
なので、そういうクラスはカプセル化にすべき。
変化する部分をカプセル化します[5]

カプセル化しなくてもいいもの データをpublicにしてもいいもの

  1. 速度の方が重要な場合[6]
  2. データ構造、メンバは今後一切変わらない!
  3. データ同士は独立している。

vec3みたいに、xyzで、絶対変わらないようなもの。
2.に関して、データ同士が有機的に関連する場合は、publicにすべきじゃない。

クラス内部でgetter/setterは使わないこと

これまでJavaに慣れ親しんだ人は、フィールドにアクセスする場合、直接操作せず、getter/setterを使う習慣が身についていると思うが、
パフォーマンスの観点から見ると、getter/setterを呼ぶよりもフィールドに直接アクセスした方が高速なので
、クラス内部でフィールドを参照する場合は、直接フィールドへアクセスすべき。

カプセル化を満たす条件

オブジェクトに対してオペレーションを実行させる唯一の方法は要求である。[1]
オブジェクトの内部データを変更する唯一の方法はオペレーションである。[1]

カプセル化していないインタフェースの例

  • C#のXAMLの部品は、たとえばラベルはLabel.Content="表示したい文字";という風にpublicアクセス出来て便利でシンプルである。

サポートサイト Wikidot.com