- - PR -
OOPがよくわかりません
| 投稿者 | 投稿内容 | ||||||||
|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2002-12-11 00:17
unibon です。こんにちわ。
この背景(public にすること)が唐突だったので補足しますと、 今回は、属性(フィールド)と操作(メソッド)の位置付けの違いを考えているので、 ひとまずカプセル化をしないことを仮定してみました。 なぜかといえば、カプセル化は、フィールドを隠蔽してメソッドを公開するので、 カプセル化が前提にあると、メソッドを重視することを推進すると思ったからです。 #私も普段はカプセル化を考えて、フィールドを private にして getter/setter メソッドを書いてます。 カプセル化が希薄だと、オブジェクトの操作のためのコードが、 クラス内のメソッドになくても良いことになります。 コードがクラス外に散逸するのは、良くはないですが、あまり気にはしません。 それよりも、ある(或る)クラス内に、ある(在る)べき属性が、別のクラス内にあって それらクラス間の関係が複雑になっていたりすることのほうが気になります。 ということで、メソッドよりはフィールドを重視するのです。 もちろんカプセル化は、やったほうが良いですが、 誤操作を防ぐとか、使いやすくするために自由度を下げるため、のカプセル化ならば、 呼ぶ側で注意すれば、カプセル化はなくてもよいです。 #これも極端な話ですが。 しかし、属性が間違っていると、これのまずさを補うためには、 呼ぶ側の注意だけでは済まなくなってきます。 と、ここまで書いて思ったのは、 メソッドを重視すると、呼ぶ側は楽になりますが、 呼ばれる側はフィールドとの辻褄合わせが負担になります。 一方、フィールドを重視すると、 呼ぶ側は、フィールドを直にアクセスするコードを書かされたり、 あるいはコロコロ変わるインターフェースの変更にお付き合いさせられたりして負担になりますが、 呼ばれる側は、フィールドの実態を素直にメソッドのインターフェースに反映しさえすれば良いので楽になります。 結局は、 メソッド重視はトップダウンでありフィールド重視はボトムアップである、 の一言で済んでしまうのかもしれません。 | ||||||||
|
投稿日時: 2002-12-11 01:57
一連の投稿、興味深く読ませていただきました。
sakitoさんの投稿ではその設計と実装の距離がかなり遠いように感じました 分析と設計の距離よりも設計と実装の距離って遠いものなんでしょうか? SE、PGで設計工程より上流の工程と実装工程の担当を明確に分けてしまうことが良くある日本の業界ですけれど、PGからのフィードバックなしで苦労したことはあります。逆にPGとして不満があっても思うようにフィードバックできなくてストレスが溜まったことも。 分析・設計者は完璧に要求を満たした機能を最高のパフォーマンスで実現できる設計をし、実装者は言われたとおり忠実に仕様をソースコードに翻訳するだけだとすると、実装は人間のすることでしょうか。それならフォワードエンジニアリングで仕様からソースを生成したほうが随分ましですよね。でも現実には分析設計は完璧じゃないし、それゆえにソースコードの作成はプログラマが行っています。こうした現状では実装者の意見は十分考慮する必要があり、フィードバックの内容次第で設計を修正することになるんじゃないでしょうか。 (実装も設計を洗練するために大きな役割を果たすと思うのですが)
利用する技術、物理的制限を設計段階で考慮しませんか? 設計って分析結果を元に実装を意識して行うものじゃないのですか?そうではないとしたら技術選択や一部のパターン適用の決定は実装工程の作業でしょうか? 設計でも実装をまったく考慮しない。という風に読めてしまったので、それじゃあ分析と設計をどのように区別しているのだろうと思いました。あと設計と実装の区別もよくわからない。 私自身は、分析・設計・実装の各工程の境界はあいまいだと思います。言葉としての定義はできるのでしょうが、実際にはケース毎に考慮すべきことが多くて範囲が不明確になるという意味です。その為に相互フィードバックにより全体を洗練していく必要があるのだと思っています。 常に分析設計はひとまとまりに扱われて実装は別扱いになってるのが気になりました。 分析設計者と実装者とか・・・ 設計実装者っていうのは有り得ないのかなと。 私自身は設計者と実装者との距離がいろいろ悩ましい状況を生んでるように感じてます。まるで設計と実装の距離感が設計者と実装者の心の距離感のよう・・・ 実装側が問題を抱えたまま設計書どおりに根性で実装してデスマーチ化するとか、設計の不備をそのまま見過ごして実装しバグが発生するとか・・・ オブジェクト指向開発で分析・設計こそが重要で比重が置かれるというのは納得しています。 プログラマの立場を考えての感情論かもしれませんが、プログラマだけが切り離されるとちょっと寂しかったんで というか、SE、PG分離に対する愚痴かも・・・ 悪夢を統べるものさんが目次で悪い印象を持ったようですが、 私も憂鬱本はオブジェクト指向をこれから始めるという人にはお薦めします。 あの本ってCからC++(Java)に移行したけれどオブジェクト指向ってよくわかんない。なんなの? って人のための本ですよね。 すでに基礎知識を持っている人が改めて読み直す必要はないのでしょうが、とっかかりにはいいと思います。 | ||||||||
|
投稿日時: 2002-12-11 10:26
tarnwoです。
こんにちは。
うーん,これってコーディング前の設計段階の問題のような気がします。 クラスが持つべき属性の抽出が重要であることは同意です。
私個人としては,それぞれのオブジェクト内の処理に変更があっても オブジェクト間のインターフェイスは変更すべきではないと思っています。 インターフェイスの変更は,特に大きなプロジェクトにおける影響度は かなりのもので,一箇所の変更が大きな工数を生む可能性があるからです。 また,どれがイミュータブルなオブジェクトなのかの判断も一見つきにくくなる 恐れと保守性の問題がありますから,推奨できるかといえば推奨したくないのが本音です。 #ドキュメントがしっかりあれば大丈夫だろうと言われればそれまでですが。 どのプロジェクトにもコーディング規約があるかと思いますが, 「アクセサを用いず,属性に直接アクセスしなさい」といったことを 推奨しているプロジェクトはどれくらいあるのでしょうか。 | ||||||||
|
投稿日時: 2002-12-11 10:28
H2さん
>一方的にメソッドのほうが大事なんだ!というのはそれこそオブジェクト指向ではありません。 すいません。私の思い違いと「重要」という言葉がまずかったようですね。 重要というのは、オブジェクト指向で重要と言っているのではなくて、外から見て重要ということです。「重要」という単語は無かったことに・・・。 気を取り直して。 以前に「メソッドが先かフィールドが先か」という話になっていましたが、問題領域(ドメインって言うんでしたっけ)からクラスを見つけ出しその関係を考える段においては、(前の投稿でもこの言葉を使いましたが)それぞれのクラスが責任を持って保持する情報やそれぞれの関係がほぼ同時に浮かび上がってきます。 例えば、「私がジュースを飲むこと」という問題領域を観察すると、「私」と「ペットボトル」がクラスとして浮かび上がってきます。そして「ジュースの残り量」は「ペットボトル」が責任を持って保持し、「私」と「ペットボトル」には飲むという片方向の関係が、ということが問題領域をクラスに分割した時点で決まります。(分析者が発見するのは遅くなる場合もあるでしょうが、決まるのはこのときです) この責任を持って保持する情報をフィールドと呼ぶのであれば、unibonさんの仰った「メソッドは後」ということになります。 で、ここに私が始めに書いた「思い違い」の部分があるのですが、私はその先について話しているつもりでした。 つまり、問題領域の洗い出しが終わり、 「じゃあそれぞれのクラスをどう作るか。「ジュースの残り量」はどうやって保持するか。ミリリットル単位の整数型で保持するか。いや、もう少し細かい値まで保持したい。じゃあ浮動小数点数にしよう。」 と考える(私の頭の中ではフィールドを決める)前にしっかり考えることがあるんじゃないですか?ということです。 フィールドは簡単に変更など、どうとでもなりますが、メソッドはそうはいきません。メソッドが決まっていないと外からは手も足もでないわけですし。 で、以前の投稿の「フィールドなんかどうでもいい」というような意味の発言になるわけですが、これはこのように受け取ってください。すなわち、 外からは フィールドなんか どうでもいい (字余り) つまり、フィールドは「メモリを節約したい」「処理スピードを上げたい」等の要望が出た場合に比較的手軽に変更できます。しかしメソッドはそうはいかないわけです。「メソッドこそじっくり考えてくださいよ」ということでした。 どう?うまくごまかせた? [ メッセージ編集済み 編集者: 一郎 編集日時 2002-12-11 10:32 ] | ||||||||
|
投稿日時: 2002-12-11 13:08
unibon です。こんにちわ。
Java だと、あるひとつのフィールドに対して、 単純な(return や変数への代入だけの1行のようなコードで) getter と setter メソッドを備えれば、 それらのメソッドを使って対応するフィールドにアクセスするのは、 フィールドを直にアクセスすることとほとんど等価になってしまいます。 したがって、アクセッサを備えたことによる隠蔽の効果はほとんど期待できず、 アクセッサを備える効果は、 (備えることによる効果というよりも逆に)アクセッサを意図的に備えていないことによる 隠蔽程度だろうと考えます。 #ほかにもデバッグ時にブレークポイントを仕掛けやすいとか、 #値検査がやりやすいなどの副次的な効果はありますが。 もちろん、コーディング規約・標準では、 アクセッサを使うことを推奨したほうが良いと思います。 使わないほうが使うよりもより良い、というメリットは、ほとんど思いつきません。 #アクセスする際の名前が短くて済み括弧が要らない、という程度でしょうか。 なお、クラスが持つ属性の種類として、基本型とそれ以外がありますが、 属性として基本型を持つものは、あとからの挿げ替えが容易なので、 こういうものは属性よりも操作を重視しても良い(悪くはない)と思います。 ただ、問題が難しいのは、属性としてオブジェクトを持つ場合です。 このような属性を持つクラスは、その属性のクラスとの間の関係ができてしまいますので、 このような属性はそれを操作するメソッド以前に重視したいのです。 #いろいろと「重視したい」と極端に書いていますが、もちろんケースバイケースの点も多いです。 | ||||||||
|
投稿日時: 2002-12-11 18:15
Javaに固有な話題と、オブジェクト指向全般の話題を区別した方がいいと思います。
オブジェクト指向で強調されているカプセル化や情報隠蔽は、「クラスを利用する側が実装の詳細を意識しなくていいようにしなさい」ということにすぎません。 そのポリシーをJavaで実践しようとすると「属性は非公開にしてメソッドで操作すべし」となる場合があるわけです。しかし、属性全てが実装詳細になるとは限りませんし、メソッドの中にも非公開にすべきものがでてくるはずです。 たとえば、オブジェクト指向言語の中には属性に対して書込み不可などのアクセス権限を定義できて、なおかつ事前・事後のイベント処理も定義できるものが存在します。このような言語では、属性へのアクセスメソッドを定義する必要がかなり減るため、属性を公開してもカプセル化は守られるわけです。 一方、java.util.Iteratorの実装クラスにどれだけのメソッドがあろうと、利用者はhasNext()とnext()さえ知っていれば事が足ります。 大事なことは「メソッドか属性か」ではなくて、「何を公開して何を隠蔽するか」です。クラスの利用者が膨大なマニュアルを前にして途方にくれてしまわないように、利用する上で必要充分な情報だけを提供する、ということです。 | ||||||||
|
投稿日時: 2002-12-12 14:00
tarnwoです。
こんにちは。 へげもん氏がご指摘の通り,スレッドのタイトルとJava特有の話とが 混同してしまっているので,別にスレッドを立てるべきかと思いますが, 「Javaにおけるコーディング方法」については, 私はWriting Robust Java Code派(?)ですので, 結局宗教論のようになってしまう気がします。
後半の2行は納得で,だからこそアクセサの重要性が出てくると思うのですが, なぜその属性に直接アクセスさせる手法を提供するのでしょうか?(^^; #そもそも,鶏が先か卵が先かの話をしていたのであれば,合点がいくのですが。 ご教授願います。 | ||||||||
|
投稿日時: 2002-12-12 14:13
unibon です。こんにちわ。
#とりあえず以下は Java を前提に書きます。 これを拝見して徒然と思ったのですが、 JDK に標準で付属の API リファレンス(JavaDoc 形式)は、 属性(フィールド)は隠蔽されて表示されません。 で、自分にとって目新しいクラスを使おうと思ってこのリファレンスを見ても、 メソッドの説明だけでいったい何の操作用のメソッドなのかが、よく分からないことがあります。 そして、こんな場合は付属のソースコードの中のフィールドを見て、 「ああ、こんなデータの持ち方だから、こんなメソッドがあって、こう使えばいいんだ」、 とやっと分かったりします。 #多くはサンプルコードを見たりして、API リファレンスを見ずに済ませることも多いですが、 #上記は、いざ見なければならなくなった場合です。 また、JavaDoc のジェネレータは、 フィールドとメソッドの表示・非表示を private/package/protected/public に応じて何段階か選択できますが、 この選択の指定がフィールドとメソッドで一緒にしか指定できないのが使いづらいと感じています。 たとえばフィールド重視だと、 private のフィールドは表示したいけど、private なメソッドは表示しない、 といった指定がしたくなりますが、それができません。 なお、開発者の立場としてはつぎの3通りに分類できると感じています。 ・クラスを設計する人(振る舞いだけを規定する人)。 ・クラスを実装する人(動くものを作る人)。 ・クラスを使う人(使うだけの人)。 JavaDoc を見る人というのは、クラスを使う人になりますが、 クラスを使う人がフィールドの実装を見たくなるというのは、なぜなんでしょう。 ちなみに、Iterator のソースコードは見たいと感じたことはありませんが、 AWT や Swing のソースコードはしょっちゅうあります。 この違いはなぜなのかが疑問です。 | ||||||||
