vieweditattachhistoryswikistopchangessearchhelp

カプセル化

オブジェクトの内部状態の有り様や振る舞いの実装を外部から隠蔽し、アクセス方法を限定することでそれらを保護すること。逆に、実装を知らなくとも決められた手段で決まった振る舞いをさせられるようなサービスを提供すること。--sumim



抽象データ型(端的にはユーザーによる型の定義)をこのように言い換えることもある。…というよりは、「カプセル化、継承、多態性」の三点セットの文脈で、もともとはその意味。この場合、前述の隠蔽(情報の…)はアクセスコントロールの結果として区別されるべきである。

オブジェクト指向プログラミング(あるいはそれをサポートする言語)に必須とされる要素の一。他に継承多態性。ただしこれは、ストラウストラップの考えをもとにした場合のオブジェクト指向(俗にクラス指向)に限った話であることについて、言及されることはあまりない。

参考:
--sumim




capsulation …でいいのかな?これの訳語が「隠蔽」だと思ってたんだけど… --CUE


encapsulation では? --sumim


あ、そうですね。--CUE


最近、「カプセル化」で悩んでいます。カプセル化とは、「構造と振る舞いをグループ化して1つの抽象物を定義し、異なる抽象物を互いに別物として分離する処理のこと」で、ほとんど「クラスを定義する」のとおんなじ意味なのでしょうか。
カプセル化と情報隠蔽は区別されて、情報隠蔽とは「クライアントに実装を公開しないこと」と POSA 本には書いてるのだそうです。助けてください。
私は、カプセル化と情報隠蔽は一緒だと思っていました。--spiral


単に手段と目的の関係ではないですか。--abee


こんなのもありました。--abee
Encapsulation is not information hiding
http://www.javaworld.com/javaworld/jw-05-2001/jw-0518-encapsulation.html


このネタはここから持ってきたのですね。--abee
[オブジェクト指向と情報処理試験 -2001年 秋-]
http://www.ogis-ri.co.jp/otc/hiroba/others/OO&siken/OO&siken05.html


カプセル化と、情報隠蔽、とくに後者については何をどこまで隠すのかについて、Smalltalk でいうところのインスタンス変数やメソッドの、さらに名称(セレクタ)か内容か存在自体かまで多岐に渡る解釈があっておもしろいですね。--sumim


クラスを定義するときに、すべてのインスタンス変数について、accessingメソッドを半ば自動的に定義してしまう流派があります。また、「Smalltalk殺すにゃ刃物は要らぬ…」で知られる「Smalltalk := nil」が使えてしまうのは、一体どういう了見なのか。さらには、instVarAt:やclassPoolで実は丸見えなのではないかとか、色々ありますね :-) --abee


>ほとんど「クラスを定義する」のとおんなじ意味なのでしょうか。
そうですね。abee さんのコメントの意図にそっているかは分かりませんが(読み返すと、たぶん違うような気がします(^_^;)。abee さんはカプセル化と情報隠蔽が目的と手段の関係なのだとおっしゃっておられる?)、カプセル化という“目的”をクラスベースのオブジェクト指向プログラミング言語を使って実行する“手段”としては「クラスを定義する」のが一般的である、というふうに考えればよいように思いますがいかがでしょう。

もちろん前提が変われば、たとえばインスタンスベースの言語なら、ハイブリッド型言語なら、オブジェクト指向言語でないなら、設計なら、分析なら…とそれに応じてカプセル化(あるいはその“もどき”)を実行する手段もいろいろと変わってくるはずです。あと、逆は必ずしも真ならずで、クラス定義が必ずしもカプセル化につながるとは限りません。Smalltalk を使ってプログラミングをすれば、それが即、オブジェクト指向プログラミングかと言うと必ずしもそうではない、というのと同じで。--sumim



遅くなりました。
あ、そうですね。この意味だと、クラスベースでない言語ではカプセル化出来ないということになりますね。今度、POSA 本を立ち読みしてきます。では、やはりカプセル化は情報隠蔽の意味も含んでいるんですね。

# オフトピですが、「未来をつくった人々」入手いたしました。やっと、いただいた DVD が見られそうです。--spiral


俺はカプセル化って語はどうもピンと来ない(ここで皆さんが悩んでるように、定義がよぉ判らん)ので、「グループ化」と「隠蔽」(これらは俺にはピンと来る(笑))という言葉(だけ)を使いたいと思ってる。で、Objectの本質はグループ化だと思ってる。隠蔽はoptional。 --戯


情報を隠蔽する事と、アクセスコントロールの話は同じじゃないですよね?
別に、Smalltalkを殺せる事と隠蔽していない(「されていない」ではなく)事は別の話だと思う。--CUE


情報隠蔽とアクセスコントロールは、とりようによっては直交する概念にも、相互に目的・手段の関係(例えば、「情報を隠すためにはそこへのアクセスを制限すればよい」と「アクセスを制御するためには、入り口を(存在するが)見えなくするのも手である」のような)になりうるので、ここではいっしょくたでいいのではないかと思います。その上で、Smalltalk では原則としてすべてが隠蔽されず、アクセス可能であるにもかかわらず、「オブジェクト指向はカプセル化だ」という既成概念を醸しだし得た妙を abee さんは説いておられるのだと私は心得ましたが、穿ちすぎでしょうか。--sumim


鷲見さん、いつもフォローありがとうございます。
カプセル化されたオブジェクトの内部状態を参照・変更するには、メッセージを介してアクセスするしかないというのが、Smalltalkの掟です。
これ即ち情報隠蔽なのですが、隠蔽という言葉に引っ張られると、それで安心と思ってしまうかもしれないという意味でした。
Smalltalkのメソッドはすべてパブリックなので、アクセシングメソッドを切った瞬間、無法状態になります。privateプロトコルに入っているやつは、プライベートにしておきましょうというお約束はありますが、これは紳士協定に過ぎません。
仮にこれを守ったとしても、上の方では出血大サービスしているわけでして、ダーティに書こうと思えばなんでもありです。特にSqueakは恥知らずなのでinstVarNamed:というメソッドまで用意してくれています。
それなので、アクセスコントロールの話抜きで情報隠蔽は語れないかなあと思っています。
同様に、情報隠蔽と変数のスコープの話を絡めるのも良いかもねというのが、グローバル変数としてのSmalltalkを持ち出した意図です。
何にしても、私はコードを書くのが好きなので(ほんとに?)、言葉の定義について議論するのがあまり得意ではないかもしれません。--abee



青木さんは情報隠蔽をアクセスコントロールを含んだ意味で使ってますね(「使わないと損をするModel-View-Controller」テキスト版, JStar版, ImageWriter版)。--abee


>Squeakは恥知らず

「SqueakはSmalltalk界のLinux」という、誉めてんだかどうだか不明な一言を、ふと思いついた。

ところで、
>「使わないと損をするModel-View-Controller」
>>CやPascal(中略)アルゴリズムをデータとして扱うには不十分

アルゴリズムを(データとして)扱えるかどうかと、変数束縛を保持できるかどうかとは、別問題なような…
変数を保持できなくて言わばROMの部分だけしか扱えなくても、アルゴリズムだと思うんだがなあ。
--戯




オブジェクトの本質とグループ化(カプセル化)


>Objectの本質はグループ化
オブジェクトの本質ってことでは、私はちょっと前までカプセル化(グループ化)が主で、そのコストを軽減するのが継承、ユーザーが享受できるメリットが多態性…という位置づけかなと思っていましたが、最近は多態性が心の中で“主”になってきています。多態性がなければなんのためのオブジェクトか、多態性を使わなければ(使えなければ)何のためのオブジェクト指向か、と(笑)。ただ、これだと多態に制約が加わる静的型チェックを行なう処理系を使っている貴族的なスタンスの人とますます話が合わなくなっちゃいますね。--sumim



>多態性を使わなければ(使えなければ)何のためのオブジェクト指向か
多態は、常に使いたいか?と問われればYESだけど、本質か?と問われれば俺の答えはNOかな。
副産物という位置付け。
真に柔軟性のあるかたち(笑)でグループ化の仕組みを提供さえして貰えれば、自作出来るから。
つまり、2つのObjectの同名属性に違うDataを代入できるのと同様に、違うFunctionを代入できれば、それはもう多態の出来上がりなので。
違う値(DataやFunction)を代入できる、つまり値をObjectごとに別々にグループ化出来るからこそ、こんな芸当が出来るわけで。
言い換えれば、多態に感謝すべきだとすれば、同じくらいにDataを別々に代入できることにも感謝すべきと思う。

代入されてたものがFunctionだったら(デフォ挙動としては)それを実行する、という仕組みはまぁ少々有りますが、うーん…
#逆にいえば、LispのListの第一要素はデフォで"実行"されるってのも、なんか不気味だと思っていたり。--戯


>多態は、... 副産物という位置付け。
よくよく考えれば、グループ化(カプセル化)などによる対象物の切り分け作業がなければ多態性の“多”は意味をもちませんね(^_^;)。この点で、すでに多態性はグループ化(カプセル化)に従属している…かな、と。ただ、多態性のないグループ化(カプセル化)と、グループ化(カプセル化)以外の手法(そんなものがあるかどうかは議論の余地はありますが)での多態性なら、多少他が不便でも後者をとるという話です。そのくらい、多態性の利用しやすさこそ我がオブジェクトの本質なり、と(今のところ)思うわけです。言い換えれば、グループ化の柔軟性やカプセル化の出来不出来のバロメータは、どのくらい自然に多態性が使えるかにかかっている、というふうにも。 HyperCard におけるオブジェクト感覚的好感(カプセル化は十分ではないが、多態性がある)も、NewtonScript や Self に感じた違和感(スロット名とアクセス名を統一してしまうと、多態の“態”の設計に制約をもたらす)も C++ や貴族的スタンス(静的型チェックなどをきっちりやろうとして多態が利用しずらくなる)に対する反発も、自分的にはこれでなんとなく説明がつきます。--sumim



いつのまにか、とても話が大きくなってしまい、あたふたしてます。でも、とても参考になるご意見が多く、感謝しています。特に、カプセル化を、グループ化で置き換えていただいたあたりが、私的にはすっきりしました。

私は今まで、カプセル化と情報隠蔽が同じモノだと思っていたので戸惑っていましたが、これでそれぞれの意味合いが納得いったと思います。それにしても、研修期間中に一単語一単語こんなに考え込んでいて、あと 1ヵ月もつのでしょうか(今は、Java を使う研修してますが、「"インナクラス"とは何か」で悩んでます。カプセル化程じゃないですけど)。 --spiral


あれ?(Javaの)InnerClassって、きちんとした定義が無いんでしたっけ?つまり言語仕様書に書いてないんでしたっけ? --戯


「Effective Java プログラミング言語ガイド」によると、「そのエンクロージングクラスに対して使えるためだけに存在すべきクラスです。」とあります。--Matubara


このページを編集 (10578 bytes)


Congratulations! 以下の 8 ページから参照されています。

This page has been visited 19016 times.