前回「第13回 静的モデル:アソシエーションのJavaの部品」はUMLの観点からの部品、Javaの観点からの部品について確認をしてきました。今回は、これらの部品を組み合わせて、Javaプログラムを前提としたUMLアソシエーションのプロファイルについて考えていきます。UMLアソシエーションのプロファイルに関する全体の構成は以下のようになります。
4.1 方針
4.2 変数のマッピング
4.3 必須の部品
4.4 集約
4.5 多重度
4.6 順序付け
4.7 変更可能性
4.8 限定子
4.9 インターフェイス指定子
4.10 配列
4.11 Collection
4.12 List
4.13 Set
4.14 SortedSet
4.15 Map
4.16 SortedMap
4.17 プロファイルのまとめ
今回は「4.5 多重度」までを解説します。
アソシエーションは、アソシエーション本体とアソシエーション・エンドから構成されます。
●4.1.1 アソシエーション本体
結論からいうと、アソシエーション本体については、特にプロファイルで必要とする部品はありません。以下にアソシエーション本体を構成する部品をプロファイルでは積極的に使用しない理由を示します。
<<アソシエーション名>>
UMLとJavaのマッピングのところで説明したとおり、アソシエーション名そのものはJavaプログラム側では利用されません。このため、プロファイルではアソシエーション名の利用方法について、特に定義しないことにします。必要に応じて参考情報として利用すればよいでしょう。
<<ステレオタイプimplicit>>
ステレオタイプimplicitは暗黙のアソシエーションが存在するという意味なので、当然Javaとのマッピングには関係してきません。必要に応じて参考情報として利用すればよいでしょう。
<<制約xor>>
制約xorは、設計の段階ではあまり利用されることはありません。また、利用されることがあっても実装方法は利用目的によって変わってきてしまいます。このためプロファイルでは特に使い方を定めません。必要に応じて参考情報として利用すればよいでしょう。
<<タグ付き値persistence>>
タグ付き値persistenceは、アソシエーションが永続化される、簡単にいうとデータベースに格納されるということを意味しています。当然Javaの基本機能ではカバーしていない機能であり、実装方法は利用目的とターゲットとなるデータベースによって大きく変わってきます。このためプロファイルでは特に使い方を定めません。必要に応じて参考情報として利用すればよいでしょう。
●4.1.2 アソシエーション・エンド
アソシエーション本体には、Javaとのマッピングで活用できる情報はありませんでした。それに対して、アソシエーション・エンドは重要な情報をたくさん持っています。本プロファイルでは、アソシエーション・エンドの部品として、必須の部品と追加情報の部品を用意します。
それでは、JavaからUMLにマップする場合はどうなるでしょうか。表1は、Javaのインスタンス変数/クラス変数のマッピングルールです。
Java | UML | |
---|---|---|
プリミティブ型 | 属性 | |
参照型 | バリューオブジェクト | 属性 |
普通のオブジェクト | アソシエーション | |
表1 変数のマッピング |
アソシエーション・エンドでは、以下の部品を必須部品とします。
●4.3.1 UMLでの表現
図1はプロファイルにおける必須形式です。上側の図が基本型、下側の図が省略形です。正確さという意味では基本型が望ましいですが、実務的な観点から省略形を用意しておくと、より簡単に使うことができます。
ターゲット・スコープがオブジェクトの場合、UMLの表現では、何も追加の指定がないので、意識する必要はありません。デフォルト値の場合は表示を省略できるという扱いになっています。ロール名はデフォルト値がないので、指定が必須になります。
●4.3.2 Javaでの実装
図1で示した必須項目が指定されたアソシエーションのJavaでの実装は以下のようになります。
public class Company { private Person employee; }
誘導可能性が変数を保持するクラスを特定します。ターゲット・スコープがインスタンス変数とクラス変数の切り分けに、ロール名がインスタンス変数名に、可視性がJavaの可視性にマップされています。
集約はUMLの通常の使い方と同じです。
●4.4.1 UMLでの表現
集約の表現は、図2に示すとおり集約指示子を使用します。図の左側が集約、図の右側が合成集約です。集約の表現に省略形はありません。集約指示子を省略すると、集約ではないアソシエーションであることを示します。
●4.4.2 Javaでの実装
Javaでは、通常のアソシエーション、集約、合成集約のいずれも以下に示すようにインスタンス変数を用いた実装になります。アソシエーション、集約、合成集約の違いを直接表現するための機能をJavaは持っていないため、この点を忠実にマップするためには、Javaプログラム内で相応の作り込みが必要となります。
import java.util.Collection; import java.util.ArrayList; public class Company { private Person employee; }
プロファイルでは、アソシエーション、集約、合成集約の機能を忠実に実現するための作り込みについては特に規定しません。つまり、UML 上のモデルでアソシエーション、集約、合成集約を正確に使い分けても、Javaへのマッピングでは無視されるということになるわけです。もちろん、これは「アソシエーション、集約、合成集約の使い分けがモデル上重要でない」ということをいっているわけではありません。
多重度はUMLの通常の使い方と同じです。
●4.5.1 UMLでの表現
多重度の表現は、図3に示すとおりUMLの通常の指定方法となります。
図3では、以下のパターンを記述しています。Javaへのマッピングを考える場合、これらのパターンでの対応が決まっていれば十分です。
また、Javaでの実装との連携を目的として以下の独自タグ付き値を導入します。
タグ付き値collectionTypeは、多重度を実現する際のインスタンス変数の型を指定します。タグ付き値collectionClassは、多重度を実現する際の実装クラスを指定します。タグ付き値collectionClassで指定されるクラスは、タグ付き値collectionTypeで指定される型として有効でなくてはなりません。以上のタグ付き値を使用したアソシエーションは 図4となります。
●4.5.2 Javaでの実装(1)
UMLの多重度とJavaでの実装の関係は表2となります。表から分かるとおり、Javaでの実装には以下の3つしか選択肢がありません。
UMLでの表現 | Javaでの表現 | ||
オブジェクト参照 | 配列 | コレクション | |
必ず1つ存在 | ○ | - | - |
1つ存在するかしないか | ○ | - | - |
1以上任意の個数個存在 | - | - | ○ |
0以上任意の個数個存在 | - | - | ○ |
固定個数個存在 | - | - | ○ |
可変個数個存在 | - | ○ | ○ |
表2 プロファイル/順序付け |
多重度が1以内の場合(「必ず1つ存在」「1つ存在するかしないか」)、オブジェクト参照として実装されます。これは、通常のマッピングなので特にここでは説明しません。多重度が「可変個数存在」の場合は、コレクションまたは配列で実装することが可能です。 それ以外のケースは、すべてコレクションで実装することが可能です。また、つまり、配列で実装できることはまれなケースということになります。また配列での実装では何かと問題があるので、本プロファイルでは積極的には利用しないことにします。以上の点から、多重度2以上の場合はコレクションを利用して実装するのが本プロファイルの選択となります。
●4.5.3 Javaでの実装(2)
多重度が2以上の場合、本プロファイルでは配列は使用せずコレクションを用いて実装します。具体的なルールは以下のものです。
このルールに沿って図3を実現したJavaプログラムは以下のようになります。
import java.util.Collection; import java.util.ArrayList; public class Company { private Collection employee = new ArrayList(); }
また図4に示した独自タグ付き値を実現したJavaプログラムは以下のようになります。 まず、タグ付き値collectionClassで実装クラスとしてLinkedListを指定した場合には以下のようになります。インスタンス変数の型にはデフォルトであるjava.util.Collectionが使用されます。
import java.util.Collection; import java.util.LinkedList; public class Company { private Collection employee = new LinkedList(); }
タグ付き値collectionTypeでインスタンス変数の型としてListを指定した場合には以下のようになります。実装クラスにはデフォルトである java.util.ArrayListが使用されます。
import java.util.List; import java.util.ArrayList; public class Company { private List employee = new ArrayList(); }
タグ付き値collectionTypeでインスタンス変数の型としてListを、タグ付き値collectionClassで実装クラスとしてLinkedListを指定した場合には以下のようになります。
import java.util.List; import java.util.LinkedList; public class Company { private List employee = new LinkedList(); }
次回は今回の続きとして「4.6 順序付け」から解説していきます。
Copyright © ITmedia, Inc. All Rights Reserved.