2009/01/13[モデリング]連載第2回のテーマは「モデルの中に隠された気付きにくい曖昧さ」です。UMLでモデルを記述する理由のひとつとして、「システムの仕様情報などを、早く、安く(低コストで)、かつ、正確に伝達したい」という点があげられると思います。UMLも所詮は言語(ある概念を表現する表記形式)の一種でしかないので、表現の「正確さ」はその言語を用いる(読み書きする)人の使い方によって大きく左右されることがあります。同じモデル図を見ても、それを読む人によっては自分(描き手)が頭の中で思い描いている構造とはまったく違った構造として解釈されることがあります。人それぞれの背景知識や理解の仕方が異なるから...という理由もあるのでしょうが、モデルに含まれている「曖昧さ」に気付かず放置されてしまっている事に起因する場合も少なくないと思います。今回は、モデル図の中に知らず知らずのうちに含まれてしまっている気付きにくい「曖昧さ」の例と、それらの曖昧さを排除するための表記例をいくつか紹介していきたいと思います。ようなクラス図が出てきました。タイヤ」の関係(その1)この例では、コンポジションの共有不可制約のため「タイヤ」側から見た「バイク」および「自動車」側の多重度は「0..1」にならなくてはならないのですが、その都合で『「タイヤ」のインスタンスは「バイク」や「自動車」のインスタンスに保有されていなくても(単独で)存在することもできる』という構造になっています。『「タイヤ」のインスタンスがポッとひとつ浮いて存在してしまうような構造は許したくない(「タイヤ」は「バイク」か「自動車」のどちらかに必ず保有されていて欲しい)』という場合はどう表現したら良いでしょうか?すぐに思い付く方法は、UMLでもっとも強力な汎用モデル要素であるコメントを使う...という手でしょうか(図2)。」を日本語的に記述してみると、『自分(この場合は1つの「タイヤ」のインスタンス)から辿れる「バイク」が空でない(相手のインスタンスが存在する)、または、自分から辿れる「自動車」が空でない』といった感じの内容になるでしょう。この条件式だとorの左辺と右辺の両方がtrueになっても良さそうで少し混乱してしまうかもしれません(実際はコンポジションの共有不可制約があるので、左辺と右辺の両方が同時にtrueになることは許されないので問題ありませんが...)。ようなものも考えられます。排他論理和)は、左辺と右辺の条件式が両方ともtrueまたは両方ともfalseだった時にfalseになる二項論理演算子です(つまり、この制約式は左辺か右辺のどちらか片方だけがtrueでもう一方がfalseの時だけtrueになります)。関連間の{xor}制約を使って表記した例です。この例の場合、あるひとつの「タイヤ」のインスタンスから見て、常に{xor}制約で繋がれている2つの関連線のうちのどちらか片方だけが有効になる...というふうに解釈します。関連間の{xor}制約は解釈が曖昧になってしまうケースもあるのであまり使わない方が良いのかもしれません。ような表記も考えられそうです。例の場合、「車体」という抽象クラスを導入することによって、「バイク」と「タイヤ」の間、および、「自動車」と「タイヤ」の間に引かれていた二本の別々の関連線を、「車体」と「タイヤ」の間に引かれる一本の関連線にまとめています。その結果、「タイヤ」側から見た「車体」の多重度は「1」になるので、これによって「タイヤ」のインスタンスが単独で存在することはなくなります。見た「タイヤ」の多重度は「2..4」と幅を持たせた形になっており、この部分は少し曖昧さが大きくなってしまっていると言えるでしょう。クラス図では「バイク」と「自動車」双方に簡単な制約式を添えて補強しています。オブジェクト制約言語OCLはUMLと一緒にOMGによって仕様定義されている制約記述のためのテキスト形式の言語構文です。UML仕様としてはUML図中に記述される制約式の書式はツール/環境依存で、どんな記述形式を採用しても良いということになっています(たとえば、JavaやC++などのプログラミング言語の構文で記述しても良い)が、OCLの構文はUML仕様と親和性が高いのでモデル中の制約式の内容を記述するための言語として標準的によく使用されています。クラス図を見てみてください。ような構造でもこのクラス図に合致します。クラス図に制約を追加するなどして補強する必要があります(図10)。」を日本語的に記述してみると、『自分(この場合は「ちょき」のあるインスタンス)から「勝ち」という関連端名で辿れるインスタンス(これは「ぐ~」クラスのあるインスタンスになる)から、さらに「勝ち」という関連端名で辿れるインスタンス(これは「ぱ~」クラスのあるインスタンスになる)は、自分から「負け」という関連端名で辿れるインスタンスと同じものでなければならない』といった感じになります。この制約式は「ぐ~」や「ぱ~」を起点(self)として記述してもOKです。この例のように、3つ以上のクラス間に役割が同様な関連線が数本引かれている場合、人間はそれらの関連線同士が何らかの相関関係を持っているかのように思い込んで解釈しまう場合があります。同じような関連端名が付けられ、似たような多重度が振られていても、クラス図上で関連線として別々に引かれているものであれば基本的にそれらの関連同士はまったく独立した別々のものとして解釈するように意識する必要があります。ないと、読む人の思い込みに頼った曖昧なモデルを描いてしまったり、あるクラス図に合致するオブジェクト群の構造バリエーションの可能性を広く想像することができなくなってしまうかもしれません。クラス図は「町内会」と「世帯主」を含む問題領域のモデルの一部です(説明のため2本の関連線を青と赤で色分けして表示しています)。ようなオブジェクト構造も許す形になっています。「稲荷町:町内会」の会長が「稲荷町:町内会」の会員ではない「田中さん:世帯主」になっています(「田中さん:世帯主」は「熊野町:町内会」の会員)。私達(日本人)は世間一般の常識から無意識のうちに「ある町内会の会員でない人がその町内会の会長役を勤めることはないだろう」という思い込みをしてしまいがちです。示したようなインスタンス群の構造もあり得るということ自体、なかなか思いつきにくかったりします(常識が邪魔をする)。いう制約があらかじめ用意されています(UML仕様の定義上、厳密にはsubsetsは制約式ではなく関連端のプロパティとして扱われます)。」という記述によって、『ある「町内会」のインスタンスから「会長」として参照される「世帯主」のインスタンスは、同じ「町内会」のインスタンスから「会員」として参照されている「世帯主」のインスタンス群の中のいずれかでなければならない』という事が示されています。