クラス図でモデリングしても実装に落とせないのは何でだ


3日前にこんなことを書いた。

http://d.hatena.ne.jp/tgk/20060804#1154714912
「問題領域の構造」と「責務の割り付け」を1枚の絵で表すことはできないのに、それをやろうとしていることが、UMLモデリングなるものの問題なのではないかと。

1枚のクラス図で、ドメインの構造と、各クラスへの責務の割り当てを、同時に表すことはできないと言いたいのだが、何かまだモヤモヤしてるので、もうちょっと掘り下げてみる。


萩本順三 これだけでわかる!初歩のUMLモデリング―基礎から各種テクニックまで第一人者が伝授!! (@ITハイブックス) のP-91に、売上を表現するオブジェクトモデリングの例がある。

+--------------+         +--------------+         +--------------+         
|     売上     |         |   売上明細   |         |     商品     |         
+--------------+         +--------------+         +--------------+         
| 日付         |  1   1..| 個数         |0..     1| 商品コード   |          
| 税金         +◆-------+ 小計         +---------+ 商品名       |
|              |         |              |         | 単価         |
|              |         |              |         |              |         
+--------------+         +--------------+         +--------------+         

ここでは商品クラスが売上明細クラスに関連付けられている。
同書には上図しか描かれていないが、仮に同じシステムに「商品マスタメンテナンス機能」があったら、そのクラス図にも商品クラスが登場するだろう。
また、「今期の商品カタログ出力機能」というのがあったら、そのクラス図にも、商品クラスがあるだろう。

+--------------+         +--------------+ 
|   カタログ   |         |     商品     | 
+--------------+         +--------------+ 
| カタログ名   |1     1..| 商品コード   | 
+              +◆-------+ 商品名       |
|              |         | 単価         |
|              |         |              | 
+--------------+         +--------------+ 

これらの商品クラスは同一の型だ。同じメソッドを持ち、同じメンバ変数を持っている。
しかし、ロードされるデータまでが同じわけではない。

クラス図に描けない情報

商品マスタメンテナンス機能で、商品「きなこクッキー」の単価を100円から120円に変更した場合、あとの2機能にどう影響すべきか。

  • 出荷済みの受注明細に関連している きなこクッキーオブジェクト の単価は、100円のままでなくてはならない。
  • 今期の商品カタログに関連している きなこクッキーオブジェクト の単価は、120円に変わらなくてはならない。

このような単価の扱いの違いは、ER図であれば明示される。


では、クラス図でこの違いを見て取ることができるのだろうか。
つまり、所有する属性と振る舞いは全く同じクラスについて、
1. カタログに載っている商品の単価は、マスタメンテ機能で更新可能である
2. 出荷済みの受注明細に載っている商品の単価は、マスタメンテ機能の影響を受けない
といったことを、クラス図で表現できるだろうか。


... いや、そういうのはオブジェクト図を描くとか、クラス図に注釈をつけるとかして表せばいいだけかもしれないけど。
私は、上の1,2は問題領域の構造そのものだと思うのですよ。
それを表現できない図からスタートしても、それ以上詳細化しようがないのではないかと。

オブジェクト指向DBではどうなの

ここまで書いて気づいたが、オブジェクト指向DBというものは「受注明細の商品とカタログの商品の違い」(=同じクラスだけどロードするデータの出所が違う)をどう処理するのだろう。
オブジェクト指向DBなら、メモリ上のオブジェクトグラフをそのまま永続化できるから簡単だ」なんて言うが、永続化されるデータが「マスタデータ(=別トランザクションの更新の影響を受ける)」なのか「トランザクションデータ(=別トランザクションの更新の影響を受けない」)なのか、どうやって判定するのだろう。
これは db4o あたりで確認してみよう。