- PR -

クラス図を基に実装する方法について

投稿者投稿内容
てっく
常連さん
会議室デビュー日: 2002/11/05
投稿数: 28
投稿日時: 2003-08-23 13:08
いつもお世話になっています、てっくと申します。

クラス図を描いた後に実装する方法について教えてください。

今以下のような関係が存在します。
[受注] [生産] [在庫]
A a 1
A b 1
A c 2
B d 3
B e 3
受注と生産の関係は1:nであり、在庫と生産の関係も1:nです。
また受注と在庫の関係も1:nになります。
受注に対して生産が複数存在するのは生産を複数回に分けるためであり、
保管場所によって在庫が別に存在するために上記関係になります。

私は初めに
[受注][生産][在庫]クラスをそれぞれ用意しました。
(実は[生産]クラスの主な役割は在庫の加減算です)
次に[受注]クラスのメンバとして[生産]クラスの配列を定義しました。
また[受注]クラスのメンバとして[在庫]クラスの配列も定義しました。
次に[在庫]クラスのメンバとして[生産]クラスの配列を定義しようとしたのですが、
生産時に初めて[在庫]クラスのキーメンバである保管場所が確定します。
そう考えると、
逆に[生産]クラスのメンバとして[在庫]クラスを定義(配列でない)し、
コンストラクタの引数として[受注]クラスのメンバである
[在庫]オブジェクト(n)を渡してやる方が自然な気がします。
生産時に新たな在庫が発生する場合も存在するのですが、
その場合は[生産]クラスのコンストラクタの引数を指定しないかnullで渡してやり、
[生産]クラス内で[在庫]クラスを生成し、それを[受注]クラスに返してやるか、
[受注]クラスで[在庫]オブジェクト(新)を生成し、
それを[生産]クラスのコンストラクタに渡してやれば・・・?

何やら泥沼にはまっている気がするのですが、
皆さんはどのように実装されるのでしょうか?
ご教授頂ければ幸いです。
小野@どっとねっとふぁん
ぬし
会議室デビュー日: 2001/10/30
投稿数: 402
投稿日時: 2003-08-23 14:02
クラス図ですが。。。

設計、分析、実装のレベルで考えたとき、どのレベルのクラス図を
書きましたか?
たぶん、実装におとすにはもっと細かいクラスを考えることが
必要な気がします。

#私もよくわかってないですが(^^;
とんび
常連さん
会議室デビュー日: 2003/07/11
投稿数: 32
投稿日時: 2003-08-23 16:20
自分も余り自信はないのですが。

[在庫]クラスのメンバとして[生産]クラスの配列を定義すれば、
[在庫]オブジェクトからその在庫を[生産]したオブジェクトがかんたんにわかりますが、
[生産]したオブジェクトから[在庫]オブジェクトを簡単には知ることが出来ません。

[生産]クラスのメンバとして[在庫]クラスを定義すれば
[生産]したオブジェクトから[在庫]オブジェクトがかんたんにわかりますが、
[在庫]オブジェクトからその在庫を[生産]したオブジェクトを簡単には知ることが出来ません。

どっちが必要かで判断されればよいのではないでしょうか。
両方必要なようなら、[生産]オブジェクトと[在庫]オブジェクトの関係を管理するクラスを別に作る(もしくは受注クラスのメンバにする)のがよいと思うのですがどうでしょうか。
Kuma
ベテラン
会議室デビュー日: 2001/12/20
投稿数: 66
投稿日時: 2003-08-24 08:52
この手のクラス設計は、データベースの正規化の考え方で良いのではないでしょうか?
第1次正規化は、「繰り返しの排除」です。配列で考えるのではなく、配列要素をレコードで考えてみたほうが素直でしょう。

ある[受注]クラスのメンバに、[生産]クラスの各メンバを実装する。
さらにその[受注]クラスのメンバに、[在庫]クラスの各メンバを実装する。
で、その[在庫]クラスのメンバに、[生産]クラスの各メンバを実装する。

こんな考えは如何でしょうか?
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2003-08-24 23:32
unibon です。こんにちわ。
#.NET は分からないのですが。

引用:

てっくさんの書き込み (2003-08-23 13:08) より:
何やら泥沼にはまっている気がするのですが、
皆さんはどのように実装されるのでしょうか?


クラスのフィールドを決める際に、どれがどれを持つのか、
すなわち、持つ・持たれるの関係が逆転してしまうことは良くあります。
RDB に比べて、クラスだと配列が使えることもあり自由度が大きく、
設計がひとつに決まらないのが普通です(RDB との対比はちょっと自信なし)。
たとえば、A が B を持つ、というクラス構造は、

コード:
class A {
    B[] children; // この A が持っている B
}

class B {
}


と、

コード:
class A {
}

class B {
    A parent; // この B を持っている A
}


の両方があります。
#コードは擬似的なものですが。
さらに、これを合体した構造もあります。つぎのような感じです。

コード:
class A {
    B[] children; // この A が持っている B
}

class B {
    A parent; // この B を持っている A
}


さらには、つぎのようなのもあります。

コード:
class A {
}

class B {
}

class AB {
    A a;
    B b;
}

class C {
    List<AB> abList;
}


ただ、4つの内のどれであっても概念的な違いはないと思います。
結局は、アクセスのしやすさと、どこまで関係を引きずる必要があるか、
の2点で選択すれば良いと思います。
たとえば、「生産」はいつまで「受注」との関係を気にする必要があるのか、という点から見た場合、
もし、生産開始したらもう受注のことを気にしなくてよいなら、
「生産」クラスに「受注」フィールドを設けるのはマズいように思います。
この場合は「受注」クラスに「生産」フィールドを設けるほうが適切かもしれません(あるいはそれ以外)。
てっく
常連さん
会議室デビュー日: 2002/11/05
投稿数: 28
投稿日時: 2003-08-25 01:39
みなさま、丁寧なアドバイスありがとうございます。

クラス設計がここまで自由度の高いものだったとは、
私の認識不足でした。
とんびさん、unibonさんがおっしゃるように実装する前に
「どう使いたいか」を洗い出す必要がありそうです。

むずかしぃ・・・
わんだらぁ
会議室デビュー日: 2002/09/25
投稿数: 3
投稿日時: 2003-08-25 05:24
初めまして。
さっそくですが、私なら[管理者]クラスを作って、[受注][生産][在庫]クラスは
[管理者]が所有するようにします。
[受注][生産][在庫]クラスから、他のクラスに対する操作が必要とするときは、
操作対象と内容を[管理者]に連絡し、[管理者]が対象のクラスに操作内容を
伝えるようにします。

会社で[受注][生産][在庫]がそれぞれ別の課で、伝票を回して仕事を処理する
イメージです。伝票を担当課へ配達するのが[管理者]ですね。

言葉では表現しにくいのですが、もっと単純化する方法もありますし、
プログラミングで「デザインパターン」と呼ばれている手法について調べられたら、
色々と参考になる考え方が見つかると思います。
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2003-08-25 06:45
既存の「在庫」を「保管場所」「商品在庫」「商品」と別々のクラスに分離すればそれで済む話です。受注は「商品」へのリンクを持ち「受注」は「商品在庫」へのリンクを持つようにします。「商品在庫」は「商品」「保管場所」へのリンクと在庫の個数を記録します。「商品」は商品の名称、型番号などを記録し、在庫の個数などの項目は記録しません。
「商品在庫」が「保管場所」によって分散する可能性があるのであれば、別クラスに分離するのが得策(というかそれしかありえない)でしょう。

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