ObjectSquare [2006 年 1 月号]

[技術講座]


J2EE 開発に求められるモデリング手法

第3回 ソフトウェア内部の構造とコラボレーション分析


正木威寛 PMP

※本稿は、技術評論社刊『JAVA PRESS Vol.38』に掲載された記事「J2EE開発に求められるモデリング手法 第3回 ソフトウェア内部の構造とコラボレーション分析」を加筆、修正したものです。JAVA PRESS 編集部の了承を得たうえで転載しています。

※一切の転載をお断りします。


はじめに

前号(第 2 回)では、要求定義でのモデリングを取り上げました。ソフトウェアとユーザ(アクター)の間で、どのようなやりとりが行われるのかを、ユースケースとイベントフローを使って定義しました。次にユースケースが表す機能(機能要求)の品質として実現しなければいけないその他の要求(機能外要求)を定義する手順を紹介しました。今回は、第 1 回のビジネス分析モデルと前号(第 2 回)のユースケースモデルをインプットとし、ソフトウェアを定義していくのに必要なモデリングの手順とそのガイドラインについて説明します。

題材のおさらい

図 1 のようなテレホンショッピングのサイトを、インターネットショッピングもできるように再構築する題材です。ビジネスモデリング、要求定義の手順とモデルについては第 1 回、第 2 回をご参照ください。

図 1 現在の業務イメージ(テレホンショッピング)
図 1 現在の業務イメージ(テレホンショッピング)

図 2 アクター「顧客」に関するユースケース図
図 2 アクター「顧客」に関するユースケース図

図 3 ユースケース「注文する」のイベントフロー
図 3 ユースケース「注文する」のイベントフロー

図 4 ビジネスエンティティ
図 4 ビジネスエンティティ

分析

分析では、あるユースケースについてのアクターとソフトウェアとのやりとり、つまりソフトウェアの外面的な振る舞いに対して、ソフトウェア内部でどのようなオブジェクト達が、どのように協調すれば、その振る舞いを実現できるかを定義していきます。これを「ユースケース分析」と呼びます。もし定義したオブジェクトの構成と協調で、対象のユースケースすべてのシナリオが説明できるのであれば、「ユースケースを実現した」といい、対象のユースケースについて分析が完了したことになります。さらにソフトウェア開発では、すべてのユースケースを効率良く実現するシステムを定義する必要があります。そのためにはユースケースを実現しながら、分析モデルを繰り返して見直し、責務を適切に分担するように洗練していくことが必要となります。

ガイドライン1 : 論理的なシステムで表す

分析では、データベースの物理テーブルやその検索方法など、物理的なシステムを検討してはいけません。この時点では関連する機能外要求や利用するメカニズムが考慮されていませんので、あくまで机上で実現した論理的なシステムということです。実際に動くユースケースを実現するには、機能外要求やその解決策であるメカニズムを検討する必要があり、ソフトウェアアーキテクチャを分析とは別に検討します。設計では、分析で定義した机上のシステムを、ソフトウェアアーキテクチャに従って、実際に動くシステムに変更します。

1.ユースケースを分析する

ここでは、机上のシステムを表すために、バウンダリクラス、コントロールクラス、エンティティクラスの 3 種類のクラスと、それらの属性の型や部分となる通常のクラスに分類して定義していきます。それぞれの説明は後述しますが、この 3 種類のクラスの構成と協調で、ユースケースのイベントフローのやりとりが実現できるように検討していきます。3 種類のクラスは、クラスのステレオタイプで図 5 のようなアイコンで表すことができます。

図 5 分析での 3 つのステレオタイプとアイコン
図 5 分析での 3 つのステレオタイプとアイコン

分析では、システムに対する分析モデルだけでなく、ユースケースに対するモデルがあります。後者を「ユースケースの実現」といいます。「ユースケースの実現」は、特定のユースケースだけについての分析モデルのビューで、ユースケースに関係するクラスを表したクラス図や、確かにユースケースが実現できることを表したコラボレーション図を作成します。図 6 は、題材のパッケージ構成例で、ユースケースの実現と机上のシステムを分けて構成しています。ユースケースの実現側は、ユースケースモデルと全く同じ階層です(第 2 回参照)。一方システム側は、さらにアクターに依存するバウンダリクラスと、依存しないコントロールクラスおよびエンティティクラスで分けています。

図 6 パッケージの構成例
図 6 パッケージの構成例

1.1 バウンダリクラスを識別する

バウンダリクラスは、アクターとの境界となるクラスで、ユースケースのイベントフローに現れる画面や帳票をバウンダリクラスとして定義します。そのための最初の作業としては、要求定義で書いたナビゲーションマップや画面スケッチを正式なものとして詳細に定義していくことが必要になります。

例としてユースケース「注文する」の基本フローから識別したバウンダリクラスを図 7 に示しておきます。

図 7 ユースケース「注文する」の基本フローから識別したバウンダリクラス
図 7 ユースケース「注文する」の基本フローから識別したバウンダリクラス

ガイドライン2 : 画面の詳細は表さない

バウンダリクラスだけで判断できるメッセージのポップアップやツールチップなどは、ひとつのバウンダリクラスとして定義しないで、バウンダリクラスの詳細な仕様として記述してください。たとえば、画面だけで行える桁数チェックのメッセージなどです。

ガイドライン3 : 画面や帳票などをステレオタイプで表す

本稿では、画面も帳票もバウンダリクラスすべてを同じアイコンで表しますが、分析モデルを利害関係者にレビューする場合などに、もう少し可読性が欲しいことがあります。その場合は、さらにステレオタイプを分類して定義し、アイコンを割り当ててビジュアルに表すこともできます。このような UML プロファイルをプロジェクトでひとつ定義しておくと良いでしょう。

1.2 エンティティクラスを識別する

エンティティクラスは、ソフトウェアに関係あるビジネスエンティティで、見落としがない限りビジネス分析モデルのビジネスエンティティから識別できます。ソフトウェアに関係があるビジネスエンティティは、イベントフローに現れているのですぐに識別できます(図 8)。

図 8 ユースケース「注文する」の基本フローから識別したエンティティクラス
図 8 ユースケース「注文する」の基本フローから識別したエンティティクラス

1.3 コントロールクラスを追加する

コントロールクラスは、これまでに識別できたバウンダリクラスとエンティティクラスを仲介するクラスです。エンティティクラスの情報をバウンダリクラスが表示している場合や、バウンダリクラスからの要求でエンティティクラスのオブジェクトを作成や変更している場合に、その間にひとつ定義します。ユースケースは、必ずエンティティクラスに何らかの作用をするので、コントロールクラスはユースケースにつきひとつ以上定義します(図 9)。

図 9 ユースケース「注文する」のクラス図
図 9 ユースケース「注文する」のクラス図

2.ユースケースを実現する

ここまでのモデリングでは、ユースケースにどのようなオブジェクトが関与するのかだけしか識別できていません。ここからは、関与するオブジェクト間のやりとりをモデリングします。ユースケースのシナリオから、関与しているオブジェクトに必要な振る舞いや、オブジェクトが持つべき属性を識別します。すべてのシナリオについてモデリングすると、そのユースケースは机上のシステムによって実現できたことになります。オブジェクト間の協調をモデリングするには、シーケンス図かコラボレーション図が使えますが、ここではコラボレーション図を使います。(理由は後述)

2.1 ユースケースのコラボレーション図を書く

ここでは、シナリオに対して机上のシステム内でオブジェクトがどのように協調するかを表すために、図 9 のクラス図に対するコラボレーション図を書きます。まだクラスには操作を定義していませんので、コラボレーション図にメッセージを書きながら、それぞれのクラスにメッセージに対応する操作を追加していきます。

ガイドライン4 : ユースケース分析のクラス図と同じ配置にする

クラス図と対比できるように、オブジェクトをクラス図と同じ配置にしましょう。こうすることにより、関連のないオブジェクト同士にリンクやメッセージを引いてしまう誤りを防げます。モデリングツールがこのようなミスを防げる場合はシーケンス図でも良いのですが、紙やホワイトボードで書く時には、コラボレーション図でクラス図と同じ配置にすることにより、ミスを簡単に防げます。たとえば、図 10 はユースケース「注文する」のクラス図である図 9 と同じ配置にしています。

ガイドライン5 : シナリオを併記する

ユースケースが実現できたかどうかわかりやすいように、ソフトウェア内部のオブジェクトの協調を表したコラボレーション図に対して、アクターから見たソフトウェアの振る舞いであるシナリオを、コラボレーション図の右側に併記しましょう。たとえば、図 10 は右側に基本フローのシナリオを示しています。

図 10 ユースケース「注文する」の基本フローのコラボレーション図
図 10 ユースケース「注文する」の基本フローのコラボレーション図

2.2 バウンダリクラスとエンティティクラスの詳細を定義する

机上のシステム内部のやりとりをより詳細に定義するには、アクターとソフトウェアの対話の中で、ソフトウェアが何を表示するのか、アクターが何を入力するのかを最初に定義する必要があります。ここでは、ユースケースに関与しているバウンダリクラスについて、画面の表示項目や入力項目を定義します。ユースケース「注文する」の基本フローでは、トップページ、商品一覧画面(図 11)、発送先入力画面(図 12)、注文完了画面(図 13)がバウンダリクラスです。(詳細な定義書は割愛しています)

図 11 商品一覧画面
図 11 商品一覧画面

図 12 発送先入力画面
図 12 発送先入力画面

図 13 注文完了画面
図 13 注文完了画面

ガイドライン6 : 画面や帳票の項目に対応するクラスや属性を識別する

ほとんどの画面の表示項目や入力項目は、エンティティクラスのいずれかの属性と対応します。それを識別し、対応するエンティティクラスに属性として追加してください。もしエンティティクラスの一部分となるクラスの属性である場合は、エンティティクラスを変更しモデルを洗練してください。またエンティティクラスの派生属性の場合もあります。その場合は、対応するクラスに派生属性を追加し、その計算式を記述してください。図 14 は、ユースケース「注文する」の基本フローの画面、図 11、図 12、図 13 の項目から、対応するエンティティクラスに属性を追加した時のクラス図です。このクラス図は、ユースケースに対してではなくシステム全体のエンティティクラスについて作成しています。

ガイドライン7 : 関連のためだけにエンティティクラスと関連するクラスに外部キーを書かない

ER 図のように外部キーを使って関係を表さず、関連の多重度やロール名で表すので、外部キーを属性として書く必要はありません。たとえば図 14 の注文明細は、ER 図では注文番号と商品コードの合成キーが外部キーとなりますが、クラス図では書きません。

ガイドライン8 : エンティティクラスの属性についてコード設計しない

エンティティクラスの属性の値をコード化するような「コード設計」は、この分析ではまだ行ってはいけません。コード設計とは、たとえば性別の「男」を 0 に、「女」を 1 に割り当てるような作業です。それはソフトウェアアーキテクチャと設計で決定することで、論理的なシステムを検討する上では必要のないことです。古いホストのシステムでは、ユーザが利用する端末にラジオボタンもリストボックスも表示する能力がないので、意味を選択させるのではなく、上記のようなコードを入力させていることがあります。このようなシステムを再構築するケースで、早期にコード設計をしようとしてしまう傾向があります。ですが、そのようなアプローチで再構築したシステムというのは、GUI になっても依然としてユーザにコードの入力を強いるようなユーザビリティが低いシステムで、カプセル化が適切に行われていない設計をしてしまいがちです。

ガイドライン9 : 一般概念を識別する

エンティティクラスや関連するクラスの属性を識別したら、それぞれの属性の型を識別しましょう。この時の型は、文字列、金額、氏名、住所などの一般概念で、小さいですが非常に再利用性の高いクラスです。氏名や住所のように、一般概念もさらに構造があることも少なくありません。図 15 は、図 14 のエンティティのクラス図で識別できた一般概念のクラス図です。

ガイドライン10 : 画面の入力項目の妥当性チェックは、対応するクラスに定義する

画面のたいていの入力項目は、妥当性のチェックが行われます。この妥当性チェックは、対応するクラスの属性についての妥当性ですので、該当する属性の定義として文章で記述します。もし対応するクラスとは別のエンティティクラスの状態と組み合わせであれば、この後のコントロールクラスの詳細として定義します。

図 14 エンティティクラスのクラス図
図 14 エンティティクラスのクラス図

図 15 一般概念のクラス図
図 15 一般概念のクラス図

2.3 コントロールクラスの詳細を定義する

ここでは、ユースケースが担う手続きを定義します。エンティティクラスや関連するクラスに含まれる小さなビジネスロジックはすでに識別されているので、エンティティクラスを横断するようなビジネスロジックを定義することになります。

ガイドライン11 : システム全体で既知の情報を提供するコントロールクラスを書かない

システム日付やサービス可能かどうかなど、システム全体で既知の情報を提供するコントロールクラスは、書いても誤りではありませんが、「ユースケースの実現」が不必要に見にくくなったり、そのメカニズムに検討の対象が脱線したりすることがあります。コントロールクラスとして定義するよりも、機能外要求として追加し、対応するメカニズムをソフトウェアアーキテクチャで検討するようにしたほうが、ユースケース分析本来の目的に集中できます。

2.4 ユースケースの実現を確認する

ここまでで、ユースケース「注文する」について、「ユースケースの実現」のクラス図(図 9)、基本フローのコラボレーション図(図 10)、エンティティクラスについての詳細を表すクラス図(図 14)、以上 3 つの UML の図を作成しました。同様に他のシナリオについても必要なクラスを「ユースケースの実現」のクラス図に追加し、コラボレーション図を作成し、エンティティクラスのクラス図に必要な属性を追加していきます。すべてのシナリオについて「ユースケース分析」が完了したら、そのユースケースは実現できたことになります。図 16 は、ユースケース「注文する」のすべてのシナリオを反映した最終的なクラス図です。図 17 と図 18 が代替フローの実現を確認するためのコラボレーション図です。ここで新たに「商品の詳細画面」(図 19)と「在庫切れ画面」(図 20)が登場しています。図 21 では、この「商品の詳細画面」から新たに商品クラスの属性を識別し、エンティティクラスのクラス図に反映しています。

ガイドライン12 : 中止するシナリオは省略する

中止するシナリオが、単に基本フローの途中で終わる場合など、中止のために特別なコラボレーションを必要としないのであれば、わざわざコラボレーション図を書く意味はありませんので、省略してかまいません。
たとえば、図 3 の代替シナリオ「3b.商品一覧画面で中止したい時」「5a.発送先指定画面で中止したい時」は、省略しても良いでしょう。

図 16 ユースケース「注文する」の最終的なクラス図
図 16 ユースケース「注文する」の最終的なクラス図

図 17 代替フロー「3a.商品の詳細を確認したい時」のコラボレーション図
図 17 代替フロー「3a.商品の詳細を確認したい時」のコラボレーション図

図 18 代替フロー「6a.注文確定時に在庫が足りなかった時」のコラボレーション図
図 18 代替フロー「6a.注文確定時に在庫が足りなかった時」のコラボレーション図

図 19 商品の詳細画面
図 19 商品の詳細画面

図 20 在庫切れ画面
図 20 在庫切れ画面

図 21 エンティティクラスのクラス図
図 21 エンティティクラスのクラス図

ガイドライン13 : ビジネスロジックやビジネスルールをすべて確認する

ユースケースが実現できているということは、「実現に必要なすべてのビジネスロジックやビジネスルールが、どこかのクラスに定義されている」ということです。したがって、ここまでの成果物で単にオブジェクトの構成と協調を UML で絵に表せているだけでなく、詳細な計算式などユースケースに関するすべてのビジネスロジックやビジネスルールが記述できていることが必要となります。実は、ここでのビジネスロジックやビジネスルールの記述が不十分なために、抜けているビジネスロジックやビジネスルールを設計者がわからずに、設計の作業が大混乱するケースがとても多いです。くれぐれも図だけ描いて納得しないようにしてください。

3.ユースケース分析を繰り返してモデルを洗練する

ひとつのユースケースについて実現できたら、他のユースケースについても同様の手順でユースケース分析を行い、分析モデルがそれらすべてを実現するようにモデリングしていきます。この時に、コントロールクラスがどんどん増えていってしまうので、責務が類似しているものをまとめてしまい、システムとして洗練していってください。

ガイドライン14 : 類似する検索をまとめる

同じエンティティクラスに対する検索は、ほとんどの場合、検索条件が異なるだけで目的は同じです。同じコントロールクラスにまとめておいて、それら検索のバリエーションがわかるようにしましょう。ただし、引数を検討して操作をまとめる必要はありません。それは設計で行うことです。設計では、分析モデルで識別されたこれら検索の操作について、妥当なシグニチャが検討されます。

ガイドライン15 : 類似する手続きをまとめる

ビジネス上の類似する手続きを、ひとつのコントロールクラスにまとめましょう。たとえば、注文する手続きと注文をキャンセルする手続きは、ほぼ逆のことをするだけで非常によく似たロジックです。このことから図 22 のユースケース「キャンセルする」のコラボレーション図では、注文をキャンセルする手続きをクラス「注文手続き」に行わせるようにしています。

図 22 ユースケース「キャンセルする」 の基本フローのコラボレーション図
図 22 ユースケース「キャンセルする」 の基本フローのコラボレーション

まとめ

今回は、ユースケースのシナリオからソフトウェア内部の構造とコラボレーションを分析し、机上のシステムとして定義していく手順についてご紹介しました。これまでに作成したユースケースモデルも、分析モデルも、これから作成するソフトウェアアーキテクチャや設計モデルも、ほとんど同じエンジニアが担当するような小規模プロジェクトでは、設計モデルの途中のモデルとして扱われるケースがあります。ですが、要求にもソフトウェアアーキテクチャにもリスクがあり、大人数で適切に作業も知識も分担して開発を行わなければならないような中規模以上のプロジェクトでは、設計以降を担当するエンジニアへの重要な橋渡しとなる、とても重要なモデルです。

参考文献

  1. Object Management Group,Inc., OMG Unified Modeling Language Specification Version 1.5
  2. Philippe Kruchten著, 『The Rational Unified Process An Introduction Third Edition』, Addison-Wesley, ISBN:0321197704


© 2006 正木威寛
Prev. Index
Prev. Index