連載
Javaオブジェクトモデリング
第2回 静的モデルの全体像
2.モデルの流れ |
本連載では、オブジェクト指向によるモデルを静的モデル、動的モデル、物理モデルの3つの切り口で扱っています。これらのモデルと開発プロセスにおけるコアワークフローの関係は、図3のようになります。図3では上段に静的モデル、中段に動的モデル、下段に物理モデルを配置しており、これらのモデルの流れを表現しています。
図3 モデルとコアワークフロー |
本連載で使用している開発プロセスのコアワークフローは、ドメイン分析、要求、システム分析、設計、実装、テストの6つのワークフローによって構成されています。この中で静的モデルは次のような形で登場します。
ワークフロー | 内容 |
ドメイン分析 | 問題領域の静的構造を表現 |
システム分析 | 解決領域の静的構造を表現 |
設計 | 実装を前提とした静的構造を表現 |
そして、実装ワークフローにおいて動的モデルと組み合わせる形で、Javaクラスに収れんしていくわけです。
3.クラス図の変遷 |
それでは、コアワークフローの中でのクラス図の変遷について見ていきましょう。クラス図が登場するドメイン分析、システム分析、設計の各ワークフローでのクラス図について取り上げていきます。
■■3.1 ドメイン分析■■
ドメイン分析では、図4のようなクラス図が使用されます。
図4 ドメイン分析のクラス図 |
ドメイン分析の目的は、問題領域のモデルを作成することにより、開発者間で共有できるボキャブラリを定義することです。かつては、ドメイン分析で抽出されたオブジェクトを詳細化することで、設計や実装につながっていくという考え方が主流でした。しかし最近では、問題領域におけるオブジェクトと解決領域におけるオブジェクトは、強い相関関係があるものの別物であり、問題領域と解決領域間のセマンティクスギャップを埋めるためのさらなる分析作業が必要だという考えが主流となっています。UP(Unified Process)におけるシステム分析は、まさにこのような分析作業を行うためのワークフローというわけです。
ドメイン分析で抽出されたオブジェクトをいくら詳細化してみたところで、システム分析を経てみなければ、解決領域において意味のあるモデルになっているか否かは分かりません。このため、ドメイン分析の段階で過度に詳細なモデルを構築することは、費用対効果の観点からあまり効率の良いことではなさそうです。
こういった理由から、ドメイン分析におけるクラス図では、属性やオペレーションに関する必要最小限の情報のみが記述されることになります。属性は必要に応じて使用しても構いませんが、属性にするかアソシエーションにするかという点について、この時点で悩んでもあまり得るものはありません。
またオペレーションについては、ドメイン分析で検討してもあまり意味がありません。オペレーションは、ドメイン分析に続く要求ワークフローにおいて、システムに対する要求仕様が定義したうえでこの要求仕様を解決領域で実現するためのオブジェクトの責務という観点から、システム分析において抽出されるべきものだからです。
いずれにしても、ドメイン分析におけるクラス図は開発者間のボキャブラリを定義するものと割り切って、過度のモデリングは避けるのが賢明であり、作成されるクラス図もそれに対応したものになります。
例えば図4の場合、クラスアイコンはクラスの名前のみを記述しており、属性やオペレーション、あるいはステレオタイプといった詳細情報は使用していません。クラスとクラスの間のアソシエーションも、実装レベルの詳細な情報は必要ありません。この図ではアソシエーション名にアソシエーションの方向を付加する程度にとどめています。
また図4では、集約(aggregation)や合成集約(composition)を用いていますが、この段階では必要ないという考え方もあります。少なくとも、単なる集約にするか合成集約にするかについて、この時点であまり深く考える必要はないでしょう。
このように、ドメイン分析で用いられるクラス図は、大枠をざっくりと示すものとなるので、実装に用いるJavaとの距離はかなり遠い状態です。つまり、ドメイン分析で用いられるクラス図とJavaとのマッピングについては、検討してもあまり意味がないのです。
■■3.2 システム分析■■
ドメイン分析は問題領域におけるボキャブラリの定義が目的でした。それに対してシステム分析は、問題領域における要求仕様を解決領域上で実現するための分析を行うワークフローです。
システム分析では図5や図6に示すようなクラス図が使用されます。
図5 システム分析のクラス図(1) |
図6 システム分析のクラス図(2) |
図5は、いわゆるロバストネス分析で使用されるクラス図です。ロバストネス分析は、ドメイン分析ワークフローで抽出したボキャブラリと要求ワークフローで抽出したユースケースのシナリオから、解決領域における基本的なアプリケーションの構造を、頑健さ(robustness)という視点をカギにして抽出する分析手法です。
UMLでは、ステレオタイプに対応して、特別に用意したアイコンを用いてよいことになっています。UPでは、システム分析におけるロバストネス分析のために、以下のような4種類のオブジェクトを定義しています。また、図7のような専用のアイコンが用意されています。
オブジェクト | 内容 |
アクター | システム外に存在しシステムと通信するオブジェクト |
バウンダリオブジェクト | アクターとの通信を行うオブジェクト |
コントロールオブジェクト | システムの振る舞いをつかざどるオブジェクト |
エンティティオブジェクト | システムの持つ永続的な状態をつかさどるオブジェクト |
図7 システム分析のオブジェクト |
ロバストネス分析では、システムの骨格の部分が分析されるだけなので、まだ実装までには距離があります。システム分析ワークフローの活動の中で、ロバストネス分析の結果を詳細化していきます。
図6は、ロバストネス分析の結果に対して、さらに詳細な分析を行った結果を反映したモデルをクラス図化したものです。ドメイン分析やロバストネス分析の段階ではあまり明確になっていなかったオペレーションが、この段階から明確になってきます。
この段階で、クラス図はかなり詳細なものになってきました。しかしシステム分析の結果得られるモデルは、実装に依存しないシステムの理想的なモデルであり、実装に必要なさまざまな要素は決定されていません。Javaでの実装にはまだ距離があります。
■■3.3 設計■■
システム分析では、ドメイン分析や要求分析による問題領域の分析結果から、解決領域における抽象的なモデルを分析しました。この結果作成されたモデルは、実装に依存しないものの、プログラムとして動作させるために必要な情報が網羅されているモデルとなります。
設計ワークフローは、この抽象度の高いモデルに対して、プログラミング言語や利用するミドルウェアといった実装に起因する情報を加えて、実装に利用できるモデルを作成する作業となります。本連載ではプログラミング言語としてJavaをターゲットにしています。また利用するミドルウェアを意識する必要がある場合にはJ2EEがターゲットとなるでしょう。
設計では図8に示すようなクラス図が使用されます。
図8 設計のクラス図 |
このクラス図を前出の図6と比較しながら、Javaでの実装を想定したクラス図について見ていきましょう。
●3.3.1 名前
図8では、クラス名などの名前として、日本語ではなくASCII文字による英語が使われています。Javaの言語仕様としては本来名前としてUnicodeを用いるので、日本語のクラス名やメソッド名を使ってもいいのですが、プログラムを取り巻く各種の環境を考えると英語を使っておく方が無難です。ローマ字を使う方法もありますが、プログラムで使う名前の数はそれほど多くならないので、できれば和英辞典を引きながら英語の単語を使うようにしておいた方がいいでしょう。
いずれにしても、システム分析までは自由に使えた名前が、設計の段階ではプログラミング言語が扱える名前しか使えないという大きな制約が入ってきます。
●3.3.2 アクセサとミューテータ
システム分析の段階では、クラスの静的な構造をつかさどる属性や関連はそのまま表現されています。しかし、これをそのままJavaクラスに持っていくことは通常行いません。
例えば図9の分析クラスをJavaで実装する場合には、リストName.javaに示すようになります。
図9 分析クラスの例 |
リストName.java |
public Name { public String getFamily() { public void setGiven(String given) { |
familyという属性に対しては、以下のような実装となっています。
- インスタンス変数familyをprivateとして宣言
- インスタンス変数familyを参照するためのメソッドgetFamilyを定義
- インスタンス変数familyを更新するためのメソッドsetFamilyを定義
属性givenも同様の実装になっています。
オブジェクト指向プログラミングのテクニックとしては、カプセル化による情報隠ぺいを重視するので、よほどのことがない限りインスタンス変数をパブリックにすることは避けるのが定石となっています。これは将来クラスの実装が変更された場合にも、クライアントに影響を与える可能性を極力低減させるためです。
このため、インスタンス変数をプライベートにしておき、このインスタンス変数にアクセスするメソッドを用意することが定石となっています。インスタンス変数を参照するメソッドをアクセサ、インスタンス変数を更新するメソッドをミューテータと呼びます。
リストName.javaのプログラムをクラス図にすると、図10のようになります。つまり設計ワークフローでは、図9の分析クラスからリストName.javaのJavaプログラムに中継するモデルとして、図10といったクラス図を生成する作業を行うことになるわけです。
図10 設計クラスの例 |
●3.3.3 多重度
多重度(multiplicity)は、アソシエーションに参加するオブジェクトの数を定義したものです。システム分析の段階では、特に重要なアソシエーションに対して多重度が設定されていれば十分でしたが、設計の段階に入るとすべてのアソシエーションに完全に多重度が設定されている必要があります。多重度が正確に定義されていないと、プログラムによる実装との関係を完全に決定することができず、設計モデルとしては不十分ということになります。
●3.3.4 可視性
可視性(visibility)は、オブジェクトを構成する情報を外部に対してどの程度公開するかを定めたものです。システム分析の段階までは、可視性についてそれほど注意を払わなくてもいいのですが、実装の段階ではすべてのモデル要素について完全に決定されている必要があります。
Javaではメソッドやインスタンス変数に対して以下の可視性を指定することができます。
public | すべてのオブジェクトに対して公開 |
protected | 自クラスおよびサブクラスに対して公開 |
private | 自クラス内のみで参照 |
package | 同一パッケージ内に対して公開 |
UML 1.3では、オペレーションや属性、アソシエーションに対して以下の可視性を指定することができます。いずれもJavaのpublic、 protected、 privateと同じ意味を持っています。
public | すべてのオブジェクトに対して公開 |
protected | 自クラスおよびサブクラスに対して公開 |
private | 自クラス内のみで参照 |
また、UML 1.4において、可視性の新しい要素としてpackageが追加されました。このため、UML 1.4ではJavaの可視性をUMLで完全に表現できるようになりました。
●3.3.5 アソシエーションロール
アソシエーションロールとは、アソシエーションに対してクラスが果たさなければならない役割(role)です。このアソシエーションロールはUMLをJavaクラスにマップするときに重要な意味を持ってきます。これについては連載第4回にて取り上げる予定です。
■■3.4 クラス図とJava■■
以上、各ワークフローにおけるクラス図について概観しました。ここで分かるのは、同じクラス図とはいっても、目的によってかなり異なった形になるということです。UMLのクラス図は、上記で取り上げたようにオブジェクト指向開発のすべての工程における静的モデルをカバーできます。さらに、C++やSmalltalkといったJava以外のオブジェクト指向言語もモデルの対象となっており、結果として非常に幅の広い仕様となっています。
また、現実の開発プロセスでのUMLの使われ方から逆算すると、設計ワークフローの成果物となるクラス図とJavaのマッピングが基本となります。この機能の範囲でのクラス図とJavaのマッピングの方法が明確になれば、目的を達成することができます。つまり、クラス図のすべての機能を洗い出して、それに対するJavaでの実装方法を考えるというアプローチはあまり効率の良い方法ではなく、設計ワークフローにおけるクラス図とJavaのマッピングにフォーカスした議論を行うのが適切ということになります。
それでは、この設計ワークフローにおけるクラス図は、どのようなモデルを表現するのでしょうか。設計ワークフローでは実装を意識したモデルを作成します。つまり、Javaをターゲットにした開発における設計ワークフローは、Java言語とのマッピングを完全に行えるものになります。前回ご紹介したとおり、設計モデルとJavaプログラムの相互変換が可能であることがオブジェクト指向開発の大きな特徴となっています。このアドバンテージを生かすためには、設計ワークフローで扱うモデルはJavaと相互変換できる範囲の仕様を利用したクラス図となっている必要があるわけです。
この点を明確にするためには、Javaの言語機能とUMLの仕様を比較しながら、Javaからボトムアップのアプローチでクラス図の使い方を決めていくことが効率の良いやり方となります。これは、「Java向けのクラス図のプロファイルを作る作業」といい換えることもできるでしょう。本連載では、このアプローチによってクラス図とJavaのマッピングについて検討していきます。
なお、さらに難易度の高い課題として、システム分析モデルを、Javaをターゲットにした設計モデルに変換するための手法が登場してきます。これはまさにオブジェクト指向開発プロセスが扱うべき問題であり、本連載の範囲外となります。もちろん、「Java向けのプロファイル」は、この問題を検討するための最重要基礎データとなります。
2/4
|
Javaオブジェクトモデリング 第2回 | |
UMLの静的モデル | |
モデルの流れ | |
クラス図のモデル | |
Javaの静的モデル |
Javaオブジェクトモデリング INDEX |
IT Architect 連載記事一覧 |