- PR -

OOPがよくわかりません

投稿者投稿内容
jack
常連さん
会議室デビュー日: 2002/07/24
投稿数: 22
投稿日時: 2002-12-07 17:54
どうしてもOOPがよくわからないので、誰か教えてください。
  私は今、大学の研究でスーパーマーケットのレジのシステムをJavaで作成しているのですが、ソースコードを見ていて、「これでいいのか?」と疑問になります。
  Javaの参考書を見ていると、ひとつのプログラムが多くのクラスに分かれています。オブジェクト指向プログラミングと聞くと、これがよい形なのかと思います。しかし、私が今作成しているプログラムでは、3つほどクラスがありますが、1つのクラスでほとんどの処理を済ましています。レジのシステムは一連の作業になっているので、1つのクラスの中で一連の処理を全て行っています。もちろん、クラスの中で共通の処理があれば、それを抜き出してメソッドとして作っていますが。
  プログラムは今の段階で2000行ほどあるのですが、そのクラスだけで1400行ほどになっています。一連の処理でも、処理ごとにいくつかのクラスに分けたほうがよろしいのでしょうか?別のクラスとして作成しているのは、売上高表示やログイン画面のように、新しいフレームを作成する必要があるものです。

  もうひとつお聞きしたいことがあります。データのset_Value(例)メソッドとget_Valueメソッドです。クラス全体で使われる変数(オブジェクト)に値を代入するときや、値を取得するときは、全ての変数に対しset_Valueメソッドとget_Valueメソッドを作成するべきなのでしょうか?
小僧
ぬし
会議室デビュー日: 2002/08/14
投稿数: 526
投稿日時: 2002-12-07 19:40
私の聞いた話によりますと、厳密なOOP(学問的)からするとJava
であっても「OOPちゃうわい!」と言われることがあるそうで、私
自身も本質的なOOP論は知りません。ちゃんと知る気もあまり無い
ので、プログラムを作るという意味でお話させていただきます。
私でしたら、まずレジを構成する要素を機能というよりも部品
(ユニット)で分けてみます。
 ・表示画面
 ・入力キーボード
 ・OMR(光学式マークリーダー)
 ・ドロワー(お金貯めとく所ね)
 ・演算ユニット
 ・ジャーナルプリンタ(レシート)
なんか足らないような多すぎるような気もしますが、物理的なユ
ニットごとに分けてみます。外部から各ユニットに何らかの動作
をさせる、今の状態を知る、設定を行う場合、必ずget/setなど
を接頭語に付けたメソッドを使います。これは実際のユニットの
動作を模倣するという意味もあるのですが、ユニットの差し替え
など、ユニット内部の動作の変化を外部に影響させないようでき
るという意味もあります。最小限の手直しで元通り動くようにさ
せるという意味ですかね。例えばドロワーを開かせるコマンドが、
別のメーカーのドロワに切り替える場合でも、メソッドの中身を
書き換えれば、呼び出し側のコードを直す必要が無くなったりし
ます。あとは、POS本体を定義するクラス内に各ユニットのイン
スタンスを組み込んであげて、POSで行われる
 ・会計
 ・集計
など用のメソッドから、各インスタンスのメソッドを呼び出して
書くと。メソッド内のコードからは先ほど作った各ユニットのメ
ソッドを呼び出してロジックを組んでいくなんていう形ですかね。
POSの部品が変わっても、POSとしての処理方法は変わらないわけ
なんで、ハード寄りの処理と商売側の処理を2つに分けることが
できます。ユニットのクラスを再利用するのも楽になりますね。
C言語なんかの時には、コードが長くなってきたらライブラリ化し
たりして、見た目に短いコードにすることで可読性を上げることが
あったのですが、オブジェクト指向では、「餅は餅屋」ということ
わざではありませんが、細かいことは専用のクラスにやらせればい
いじゃん!という思想になるので、一つ一つの機能はシンプルなコ
ードで書けます。POSのメイン処理のコード自体も短くなりますね。
なんか、ここまで要求されてないかもしれないんですが、こういう
分割のしかたもあるということで。参考まで。

>クラス全体で使われる変数(オブジェクト)に値を代入するときや、
値を取得するときは、全て>の変数に対しset_Valueメソッドと
get_Valueメソッドを作成するべきなのでしょうか?

面倒くさいでしょうが使った方がいいと思います。クラス内部から
しか操作しないようにしておけば、期待した動作をしない場合でも
原因がクラス内部だけに限定されるので楽です。




[ メッセージ編集済み 編集者: 小僧 編集日時 2002-12-07 19:49 ]
sakito
常連さん
会議室デビュー日: 2002/08/25
投稿数: 23
投稿日時: 2002-12-07 21:27
OOP=オブジェクト指向プログラミングとは
オブジェクト指向分析により分析し、オブジェクト指向設計により設計し、それをオブジェクト指向言語によりプログラミングする事です。

オブジェクト指向ソフトウェア開発を正確に実践するには分析設計はもっとも重要な部分です。

通称「憂鬱本」とよばれる以下の書籍を参考にしてください
http://www.amazon.co.jp/exec/obidos/ASIN/4881356194/
注:説明言語はC++ですがJavaを知っていれば問題なく読めます

jack
常連さん
会議室デビュー日: 2002/07/24
投稿数: 22
投稿日時: 2002-12-08 22:20
返答ありがとうございます。小僧さんが一例を示してくださったクラス分けの、

・表示画面
・入力キーボード
・OMR(光学式マークリーダー)
・ドロワー(お金貯めとく所ね)
・演算ユニット
・ジャーナルプリンタ(レシート)

がありますが、私のプログラムでは、表示画面以外は全て一つのクラスになっていました。キーボードなどの入力処理をして、演算メソッドを呼び出し、レシート書き出しメソッドを呼び出して、ドロワーメソッド(在高管理)を呼び出すという処理を一つのクラスで処理していました。やはり、これらのメソッドはクラスとしたほうが良かったのですね。

>>例えばドロワーを開かせるコマンドが、別のメーカーのドロワに切り替える
>>場合でも、メソッドの中身を書き換えれば、呼び出し側のコードを直す必要
>>が無くなったりします。

なるほどと思いました。まだまだ、経験が足りないので、多くの人の意見を聞いて参考にしていきたいです。

sakitoさんの、通称「憂鬱本」も是非読んでみたいです。なぜ、「憂鬱本」なのかを知ってみたいと思います。

未記入
ぬし
会議室デビュー日: 2002/03/28
投稿数: 255
投稿日時: 2002-12-09 13:23
>  プログラムは今の段階で2000行ほどあるのですが、そのクラスだけで1400行
>ほどになっています。一連の処理でも、処理ごとにいくつかのクラスに分けたほう
>がよろしいのでしょうか?
結論から言えば,ケースバイケース,でしょう.
ただ,一つのクラスにほとんどの処理が集中しているとなると,
設計として良くない可能性が高いとは言えます.

クラス設計については奥が深く,一筋縄ではいきません.
「Effective Java」,「リファクタリング」あたりは,
難しいですがお勧めです.

この他,デザインパターン関係の書籍も最近は腐るほど出てますので,
一冊好きなのを選んで目を通しておくことを勧めます.

>クラス全体で使われる変数(オブジェクト)に値を代入するときや、値を取得する
>ときは、全ての変数に対しset_Valueメソッドとget_Valueメソッドを作成する
>べきなのでしょうか?
これもケースバイケースですね.

ただ,単にそのままデータを取り出したり書き込んだりするだけの
メソッドならば,そのメソッド自体が無意味な可能性が高いでしょう.
これまで設計を見直すことをお勧めします.

いずれにせよ,良い設計というものは極めて奥が深く,一朝一夕に習得できる
ようなものではないということは,肝に命じて置いて下さい.
sakito
常連さん
会議室デビュー日: 2002/08/25
投稿数: 23
投稿日時: 2002-12-09 14:53
引用:

sakitoさんの、通称「憂鬱本」も是非読んでみたいです。なぜ、「憂鬱本」なのかを知ってみたいと思います。


あ、これは説明不足だったかも。書名が「憂鬱なプログラマのための〜」って題名だからです。内容読むと結構よい事かいてあります。
まあJavaではちょっと違う部分もありますが、参考になるでしょう。

これだけではなんですので、追加で記述しておきます。
クラス設計ですが、通常はメソッドから先に分析します。
よって属性にあわせてメソッドを作成する事はないです。
そのため、

>クラス全体で使われる変数(オブジェクト)に値を代入するときや、値を取得する
>ときは、全ての変数に対しset_Valueメソッドとget_Valueメソッドを作成する
>べきなのでしょうか?

という質問の回答は自動的にでます。
まずクラスではメソッドが先です。
メソッドが先であるからテストファーストが可能なのです。

といった感じです。

参考になれば。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2002-12-09 16:42
unibon です。こんにちわ。

引用:

jackさんの書き込み (2002-12-07 17:54) より:
レジのシステムは一連の作業になっているので、1つのクラスの中で一連の処理を全て行っています。もちろん、クラスの中で共通の処理があれば、それを抜き出してメソッドとして作っていますが。



#私も OOP がなにかは、きちんとは知らないですが、
#少し慣れた者から見て、初学者のかたが陥りやすいと思う点について書きます。
#(常に正解というわけではありませんが、こういう観点もあるということで。)

処理(メソッド)を中心に据えて考えていることに大きな問題があると思います。
状態(フィールド)をまず中心に考えて、そのつぎにそれらフィールドが属するクラスを考えて、
処理(メソッド)は最後に考えたほうが良いと思います。

また、「共通の処理」があった場合には、
コードが単に重複している場合と、
処理が似ているけど微妙に異なる場合、
の2つに大別できると思います。
前者ならば、単純に処理を共通化すればよいかもしれませんが、
後者ならば、異なるのにはそれなりの理由があることが考えられます。
無理に共通化するよりも、逆にクラスを分けることを考えると良いかもしれません。
sakito
常連さん
会議室デビュー日: 2002/08/25
投稿数: 23
投稿日時: 2002-12-09 18:07
引用:

unibonさんの書き込み (2002-12-09 16:42) より:。
#私も OOP がなにかは、きちんとは知らないですが、
#少し慣れた者から見て、初学者のかたが陥りやすいと思う点について書きます。
#(常に正解というわけではありませんが、こういう観点もあるということで。)
処理(メソッド)を中心に据えて考えていることに大きな問題があると思います。
状態(フィールド)をまず中心に考えて、そのつぎにそれらフィールドが属するクラスを考えて、処理(メソッド)は最後に考えたほうが良いと思います。



この考え方は変です。
極端に言ってしまうとクラスにとって属性など変化してもまったくかまわないものです。
設計中に属性はどんどん変化してもかまわないものです。
変化が絶対にしてはいけない物はメソッドのみです。
オブジェクト指向の「オブジェクト」という単語には「物」という意味のみでなく「客観」という意味があります。
あくまでもオブジェクト指向においてはクラスは客観的な物です。
クラスをどのように操作するか(メソッドの分析)が先にくるのは必然です。
すごく極端に言えばメソッドで必要だから属性があるのです。

とかなり極端に書きましたが、普通は操作から先に分析するものです。
属性の決定は分析としてはあとの方にならないと決定する事は不可能ですし、メソッドが決定してないとインターフェースが常に変化するなんていうアホなプロジェクトになりかねないのでやめてほしい。。。

スキルアップ/キャリアアップ(JOB@IT)