静的モデル:リレーションシップ(2)Javaオブジェクトモデリング(8)

» 2003年02月13日 12時00分 公開
[浅海智晴,@IT]

 本連載の目的は、「UMLのフルスペックをいかに使いこなすか」ではなく、「Java開発をターゲットにしたUMLの使い方」を明確にする点にあります。そして、Javaをターゲットにした設計モデルを作成するために必要なUMLのプロファイルを提案することが最終的な目標となります。

 この目的には、メタモデルを起点としたトップダウンのアプローチではなく、ノーテーションを起点としたボトムアップのアプローチが有効です。もちろん、これはUML利用者の立場から見たUMLがノーテーションであることによります。

 以上の点から、本連載では「第7回 静的モデル:リレーションシップ(1)」で解説した「UMLノーテーションから見たリレーションシップ」のモデルをベースに議論を進めていくことにします。



4.リレーションシップの全体像

4.1 リレーションシップの関係

 本連載で用いるリレーションシップの全体像を再度振り返っておきましょう(図1)。

ALT 図1 リレーションシップの関係

 リレーションシップは大きく、アソシエーション、汎化、リアライゼーションに分けることができます。また、以上のいずれにも属さないリレーションシップがディペンデンシィとなります。アソシエーションは、集約と集約以外のアソシエーション、さらに、集約は合成集約と合成集約以外のアソシエーションに分けられます。

4.2 アソシエーションの用語法

 アソシエーションの重要な部分集合には、集約があります。アソシエーションは大きく分けて以下の3つに分類することができます。

・(集約でない)アソシエーション

・(合成集約でない)集約

・合成集約

 アソシエーションには集約と集約でないアソシエーションの2種類のアソシエーションがあります。また、集約には合成集約と合成集約でない集約の2種類の集約があります。このため、厳密には単にアソシエーションといった場合、集約でない普通のアソシエーションなのか、集約なのかの区別はつきません。また、集約にも合成集約との間に同様のあいまいさが存在します。そこで本連載では、アソシエーションを「集約でないアソシエーション」、集約を「合成集約でない集約」の意味で用いることにします。

4.3 ディペンデンシィの用語法

 リアライゼーションは前述したようにメタモデル上はDependencyの一種であるAbstractionに対してステレオタイプrealizeを指定したモデル要素となっています。分かりやすくいうとリアライゼーションはディペンデンシィの一種ということになります。しかし、この定義通りの用語法を用いると繁雑になってしまうので本連載では、ディペンデンシィを「リアライゼーションでないディペンデンシィ」の意味で用いることにします。

5.各リレーションシップの機能

 前節では、リレーションシップの「本連載内での定義」を再確認しました。それでは以下、本連載で用いる各リレーションシップの機能について簡単に説明しておきます。イメージをつかんでいただくために、簡単なUMLとJavaのマッピングにも触れておきます。図の中に登場する細かな修飾については今回は説明しませんが、次回以降各リレーションシップの説明の中で詳しく取り上げる予定です。

5.1 アソシエーション

 アソシエーション(association、関連)は、分類子のインスタンスの間にコネクションがあるというリレーションシップです。アソシエーションの使用例を図2に示します。OrderHandlerのオペレーションが、パラメータという形でOrderとのコネクションを持つというリレーションシップを示しています。

ALT 図2 アソシエーションの使用例

 リスト1に、このUML図に対応するJavaソースの例を示します。receiveOrderメソッドの引数としてOrderが参照されています。

リスト1 OrderHandler.java
public class OrderHandler {
    public void receiveOrder(Order order) {
        recordOrder(order);
        delivery(order);
    }       public void recordOrder(Order order) 
{
        ...
    }     
    public void delivery(Order order) {
        ...
    }
}

5.2 集約

 集約(aggregation)は、クラスが別のクラスの一部であることを表すアソシエーションです。集約の使用例を図2に示します。OrderItemProductを構成要素として持っています。ただし、OrderItemが消失しても、これと同期してProductは消失しないという関係を示しています。

ALT 図3 集約の使用例

 このUML図をJavaにマップしたものがリスト2です。この例でも分かる通り、集約は通常Javaの属性として実装されます。

リスト2 OrderItem.java
public class OrderItem {
    public Product product;
}

5.3 合成集約

 合成集約(composition、composite aggregation)は、クラスが別のクラスの完全な一部になっていることを表す集約です。合成集約の使用例を図4に示します。Orderは複数のOrderItemと合成集約の関係を持っています。つまり、Orderが消失すれば同時にOrderItemも消失するという強い依存関係を持っているわけです。

ALT 図4 合成集約の使用例

 1つのOrderが複数のOrderItemを持っているという関係を実装するために配列を用いています。このUML図をJavaにマップしたものがリスト3です。

リスト3 Order.java
public class Order {
    public OrderItem[] items;
}

 Javaでの実装では、合成集約から導かれる「Orderが消失すると同時にOrderItemも消失する」という部分を実装に反映することはかなり難しくなってしまいます。このあたりが、UMLからJavaへのマッピングで苦労しそうなところとなるわけです。

5.4 汎化

 汎化(generalization)は、より汎用的なモデル要素とより特殊な要素の間にあるリレーションシップです。いわゆる継承(インヘリタンス)と呼ばれているものです。ただし、継承と汎化は厳密には意味が異なります。汎化の使用例を図5に示します。より汎用的なクラスであるAbstractionOrderReceiverと、このAbstractionOrderReceiverの特殊化したクラスであるWebOrderReceiverの間に汎化の関係があることを示しています。

ALT 図5 汎化の使用例

 このUML図をJavaにマップしたものがリスト4です。UMLの汎化はJavaではextendsによって表現されます。

リスト4 WebOrderReceiver.java
public class WebOrderReceiver extends AbstractOrderReceiver 
{
} 

5.5 リアライゼーション

 リアライゼーション(realization、実現)は、仕様のモデル要素とその実装のモデル要素の間にあるディペンデンシィです。リアライゼーションの使用例を図6に示します。クラスAbstractionOrderReceiverがインターフェイスIOrderReceiverを実現する関係にあることを示しています。

ALT 図6 リアライゼーションの使用例

 このUML図をJavaにマップしたものがリスト5です。クラスがインターフェイスをリアライゼーションする関係はJavaではimplementsで表現されます。

リスト5 AbstractOrderReceiver.java
public abstract class AbstractOrderReceiver 
implements IOrderReceiver {
}

 このとき、IOrderReceiverリスト6のようなJava interfaceとして実現されます。

リスト6 IOrderReceiver.java
public interface IOrderReceiver {
} 

5.6 ディペンデンシィ

 ディペンデンシィ(dependency)は、アソシエーション、汎化、Flow、メタ関係以外のあらゆるリレーションシップを総称した用語です。ただし、前述した通り、本連載のディペンデンシィは、さらにリアライゼーションを除外したものになります。ディペンデンシィの使用例を図7に示します。AbstractOrderHander内のオペレーションがOrderHandler内のオペレーションを呼び出す、という関係を示しています。

ALT 図7 ディペンデンシィの使用例

 このUML図が表現するJavaプログラムの例がリスト7です。

リスト7 OrderHandler.java
public class AbstractOrderReceiver {
    private OrderHandler handler;
    public void receiveOrder(Order order) {
            handler.handleOrder(order);
    }
}

5.7 クラス図の例

 最後に、今回登場したリレーションシップを使ったクラス図の例を図8に示します。

ALT 図8 リレーションシップを使ったクラス図の例

 このような形で、リレーションシップを駆使してクラスやインターフェイスの関係を明らかにしていくことが静的モデルの主眼となります。


 今回は、分類子と並んで静的モデルの核となるモデル要素であるリレーションシップについて概観しました。リレーションシップそのものは抽象的な概念ですから、Javaとの直接の関係は出てきません。リレーションシップを具象化したモデル要素であるアソシエーション、汎化、ディペンデンシィがJavaとの対応関係を持ってきます。

 次回から、アソシエーション、集約、合成集約、汎化、リアライゼーション、ディペンデンシィの順番でJavaによる実装を考えていきます。

Copyright © ITmedia, Inc. All Rights Reserved.