- PR -

ビジネスロジックの実装について

1
投稿者投稿内容
てっく
常連さん
会議室デビュー日: 2002/11/05
投稿数: 28
投稿日時: 2003-10-12 03:55
いつもお世話になっています。

クラスの設計・実装についてご教授ください。

今RDB上に「社員」表と「組織」表が実装されているとします。
これをJavaBeansなどで「社員」クラスと「組織」クラスにするとします。
例えば「社員」クラスには
・createメソッド(「社員」表へのinsert)
・storeメソッド(「社員」表のupdate)
・removeメソッド(「社員」表からのdelete)
・findメソッド(「社員」表からのselect)
などが実装されているとします。
「組織」クラスも同様であるとします。

単純に個々のRDB表へアクセスする場合はこれでも問題なさそうです。
しかし、例えば
「社員とその所属組織を表示したい」であるとか、
「組織に所属する社員の総数(または社員情報そのもの)を表示したい」といった
要求に応えようとした場合は、どうするのでしょうか?
(SQLだと簡単に検索できるレベルの話なのですが・・・)

私は最初に
単純にSQLで表同士のJOINをしてSELECTする処理を実装したメソッドを、
「社員」クラスや「組織」クラスに実装する方法を考えました。
でもこれでは処理が増えれば増えるほど、メソッドが増えていったり、
果ては「社員と組織を同時に取得する」クラスなんかも登場しそうです。。。
それに複雑な検索処理の場合、一体どちらのクラスに実装すればよいのか、
私などは路頭に迷ってしまうような気もします。
それはちょっと・・・。

次に考えたのは、
どんな処理であろうと各クラスを個別に扱う方法です。
つまり「社員と組織」の情報が知りたい場合は、
社員#findメソッドをコールした後、組織#findメソッドをコールするイメージです。
本来SQL一発で処理できる所を、複数回に分けることになります。
DBへの接続はコネクションプーリングなどを利用するとしても、
正規化された表へのアクセスはSQLの乱発を招き、パフォーマンスが心配です。。。

・・・と、私は頭を抱えてしまったのですが、
皆さんはどのような手法で解決されているのでしょうか?
迷える子羊をお導きください。。。m(_ _)m
Kissinger
ぬし
会議室デビュー日: 2002/04/30
投稿数: 428
お住まい・勤務地: 愛知県
投稿日時: 2003-10-13 01:48
てっくさん、こんにちは。

以下、私のやり方ですので、最適な解ではないかもしれませんが、
・社員とその所属組織を表示 →「社員」クラス
・組織に所属する社員の総数を表示 →「組織」クラス
これらよりももっと両者の関係が複雑な関係を扱うなら、それは
どちらのクラスの役割でもないかもしれません。
無理矢理どちらかのクラスに入れてしまおうとしないほうがよい
場合も多いです。
(機能がそのクラスの役割なのかどうかを考えます。)

「組織表」というクラスが別にあっても良いかも知れません。
そのクラスが、「各クラスを個別に扱う」のか「SQL一発で処理
する」のかは隠蔽できるわけです。(後から変更してもインタ
ーフェースに影響はない。)

ちょっとづつ違った機能(要望)を、メソッドとしてどんどん追
加するやり方は汚くなります。(見た目のスマートさの事ではな
く、保守性とか再利用性が悪くなる。)
ですから、その要求される機能を「クラス」として実現します。
可能なら、それらの(後からつぎつぎに追加されるだろうクラス)
の生成や呼び出しインターフェースを決めておく(『ファクトリ
パターン』『コマンドパターン』)にするというのが良いかと思
います。

あと、ちょっと古いですが、OMT本の 3.3.2には
「関連をクラスとしてモデル化することは有効である。」
というのもありますので、参考になるかも。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-10-13 10:29
unibon です。こんにちわ。

この問題は OR マッピング(object-relational mapping)の領域だと思います。
そして、OR マッピングは難しいです
(私もあまり良く理解していませんが難しいことは分かっている)。
こちらの掲示板だと、最近だと、
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=6517&forum=12
などに話題がありますね。
本来ならば、OR マッピングとはなにかを十分に踏まえた上で、
設計されたほうが良いと思います。

しかし、(再度書きますが) OR マッピングは難しいので、
もし、モデルがあまり複雑ではなく、
OR マッピングを使わないで(考えないで)済むなら
使わないでやってしまうのもひとつのソリューションでしょう。
以下、それを前提に書きますと。

引用:

てっくさんの書き込み (2003-10-12 03:55) より:
私は最初に
単純にSQLで表同士のJOINをしてSELECTする処理を実装したメソッドを、
「社員」クラスや「組織」クラスに実装する方法を考えました。
でもこれでは処理が増えれば増えるほど、メソッドが増えていったり、
果ては「社員と組織を同時に取得する」クラスなんかも登場しそうです。。。
それに複雑な検索処理の場合、一体どちらのクラスに実装すればよいのか、
私などは路頭に迷ってしまうような気もします。


多少、コードの量が増えてもこれの延長で済みそうならば、
これでやってしまうほうが良いかもしれません。

引用:

てっくさんの書き込み (2003-10-12 03:55) より:
次に考えたのは、
どんな処理であろうと各クラスを個別に扱う方法です。
つまり「社員と組織」の情報が知りたい場合は、
社員#findメソッドをコールした後、組織#findメソッドをコールするイメージです。
本来SQL一発で処理できる所を、複数回に分けることになります。
DBへの接続はコネクションプーリングなどを利用するとしても、
正規化された表へのアクセスはSQLの乱発を招き、パフォーマンスが心配です。。。


このやりかたは、おっしゃるようにパフォーマンスの面で不利です。
てっく
常連さん
会議室デビュー日: 2002/11/05
投稿数: 28
投稿日時: 2003-10-13 12:30
Kissingerさん、unibonさん、ご回答ありがとうございます。

やはりこれは(私にとって)難しい問題だったのですね。
まずはSQLを素直にメソッドに実装するような形で取り組んでみます。

ところで(私の勝手な思い込みかもしれませんが)、
DBの接続と切断は一つのメソッド内で完結すべきものなのでしょうか?

そうしますと例えば更新系の処理などで、
「一つのトランザクション内で複数のUPDATE文を発行する」
と言った処理を組み込むためには、
一つのメソッド内で実装しなければいけないような気がします。

「社員」と「組織」を同時に更新することは滅多に無いかもしれませんが、
このように複数のクラス(RDB表)を更新するような処理の場合、
どのように実装すれば良いのでしょうか?

ちなみに私の貧困な脳ミソが生み出したアイディア(?)は、
ビジネスからの要件に応じて柔軟にクラスを増やしていく、というものでして、
上記の例で言いますと
「社員」と「組織」を同時に更新するクラスを作ることになってしまいます。
何だかぐちゃぐちゃになっているような・・・。

唐突な質問ばかりで恐縮なのですが、ご教授いただければ幸いです。
よろしくお願いします。
やまろう
常連さん
会議室デビュー日: 2003/10/13
投稿数: 35
お住まい・勤務地: 埼玉・東京
投稿日時: 2003-10-13 13:39
やまろうと申します。初投稿です。よろしくお願いします。

「DBの接続と切断は一つのメソッド内で完結すべきものなのでしょうか?」
とのことですが、EJBを使う場合はそうすべきだと思います。

おそらくご存知だとは思いますが、
EJBのメソッド内で自分で一つのコネクションを持ちまわって
トランザクションを管理しないで、接続、切断を繰り返しても、
EJBの1メソッドで1トランザクションとなります。コネクションプーリングや
コネクションシェアリングってやつです。

その為、"「社員」と「組織」を同時に更新するクラスを作る"必要はなく、
"「社員」と「組織」を同時に更新する"処理をEJBのメソッドの中に
実装すれば良いと思います。

最近、EJBは複雑で面倒ばかりでメリットが少ないというようなことを言われています
が、この「トランザクションをコンテナに管理させる」機能はEJBの大きなメリットだと
思います。

それと以前の開発でDBアクセスをEJBデザインパターンの「Data Access Command」
パターンを採用したんですが、(「Data Access Command」はSQLのパラメータを
set○○して、execute()を呼び、close()を呼ぶっていうもの)
ビジネスロジック内にCommandの大量のset○○が書かれ、さらにclose()を
呼び忘れるといったことがありました。その為、DBのcloseはコンポーネント
の中に隠蔽して閉じ忘れを防止する設計がいいと思います。その方が
呼び出し側が楽です。

EJBを使用しないのでしたら、一つのconnectionをずっと持ちまわって
自分でコミット、ロールバックをするのでしょうから、それらを隠蔽するために
"「社員」と「組織」を同時に更新するクラスを作る"という選択は間違ってないと
思います。
syo
常連さん
会議室デビュー日: 2003/08/17
投稿数: 43
投稿日時: 2003-10-13 15:41
お世話になっております。

引用:

てっくさんの書き込み (2003-10-13 12:30) より:

ちなみに私の貧困な脳ミソが生み出したアイディア(?)は、
ビジネスからの要件に応じて柔軟にクラスを増やしていく、というものでして、
上記の例で言いますと
「社員」と「組織」を同時に更新するクラスを作ることになってしまいます。
何だかぐちゃぐちゃになっているような・・・。




あまり良い方法ではないのかもしれませんが、
似たような状況で私が採用した方法は、
・「社員」関係の情報を扱う汎用クラスを作成
・「組織」関係の情報を扱う汎用クラスを作成
で、Beanの中からそれを順番に呼び出して処理を行う、といったものでした。

単に「社員」の情報のみが必要な場合でも、汎用クラスとは別にBeanを作成して、
そこから「社員」クラスを呼び出すようにしています。
アプリケーションの仕様上、いろんなところで「社員」情報の参照を行っているため、
このような実装にしました。

DBへのコネクションは「社員」クラス、「組織」クラスの側で行うように
していますので(呼び出し元で意識しなくて済むように)、
コネクションプールを使用しているとはいえ、パフォーマンスを落としている可能性がありますが・・・。
未記入
ぬし
会議室デビュー日: 2002/03/28
投稿数: 255
投稿日時: 2003-10-13 17:30
>今RDB上に「社員」表と「組織」表が実装されているとします。
>これをJavaBeansなどで「社員」クラスと「組織」クラスにするとします。
他の条件が良く分からないので断言できませんが,おそらく「組織」も「社員」も主要な
オブジェクトではない,極論すればどーでもいい部分だと思います.とりあえず,それらは
枝葉末節の実装依存部分と考え,頭をリセットして全部忘れてからクラス設計を開始します.

中心となるのこれらの実装依存のデータ構造(的な)部分よりも,
>「社員とその所属組織を表示したい」であるとか、
>「組織に所属する社員の総数(または社員情報そのもの)を表示したい」といった
要求に応えようとした場合は、どうするのでしょうか?
こちらの方だと思います.こちらの方から設計を見直すべきだと思います.
#重要ではないからと言って,必ずしも「社員」クラスや「組織」クラスが無くなるとは限らない.

>(SQLだと簡単に検索できるレベルの話なのですが・・・)
だからこそ,おそらくその部分はSQLにやらせるでしょう.そっちの方が簡単なのだから.
てっく
常連さん
会議室デビュー日: 2002/11/05
投稿数: 28
投稿日時: 2003-10-14 00:31
みなさま、私のために貴重なアドバイス、ありがとうございます。

やはり「何がしたいか?」という部分を明確にすることが大事、
ということでしょうか?
(これってキホンだったりして・・・

まずはあれこれ考えずに(背伸びをせずに)
素直に組み立ててみようかと思います。
その上で問題点などを洗い出してみようと思います。

それにしても、むずかしい・・・
1

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