[開発プロセス#4] 開発するシステムのモデリング

Webシステムに関する開発プロセスの続きです。

システムを設計する上では様々なモデリング手法が使われます。要求から要件を導く上で、ユースケース図を作ることや、ドメインモデルのクラス図あるいはデータベース構造を記述するER図などが使われます。開発プロセスにおいてそれらの関連性を検討に入れて、各段階で何を目的にどんな図を記述すれば良いかということが規定されていることで、作業がスムーズに行われることを目指します。例えば、ICONIXでは、ユースケース図を記述した上で、ユースケースで抽出された場面で何が行われるかをロバストネス分析を行い、より詳細化しつつユースケース上の漏れを発見するという手順を行います。ここで議論するプロセスでも、同様な流れで、ユースケースの検討の後に、ロバストネス図を記述することで、詳細設計に入ることを意図します。

なお、ユースケース図は非常にシンプルな図であり、UMLの中では唯一、エンジニアではない方々にも読み解いてもらえる可能性のある図であります。その意味では、要求を要件としてまとめてシステム境界を検討したり、利用者から見た動作が必要十分に揃っているかを検討するには役立ちます。しかしながら、ユースケース記述、つまり、1つ1つのユースケースについての処理手順をこの段階できちんと書くよりも、コミュニケーション図への記述に移った方が、効率的と考えます。ユースケース記述に記載するような内容は、事実上、コミュニケーションズにも登場します。一方で済むのなら、同じ事実を異なるドキュメントに記述することでのドキュメントのメンテナンスタスクが重くなる点を考えても、一方だけにすべきです。もちろん、エンジニアでない顧客とのやりとりには、ユースケース記述も有効かもしれませんが、それでも「動いていないシステム」について可否の判断は通常は誰もできないと思われます。ユースケースで大枠を固めた上で、個別の処理はロバストネス図で詰めるのが作業効率が高いと言えます。

ロバストネス図はUMLで定義されたダイアグラムではありません。1992年に出版されたIvar Jacobsonらの “Object-Oriented Software Engineering, A Use Case Driven Approach” において分析モデルとして記述方法が提示されています。ICONIXの手法を解説したダグ・ローゼンバーグらの書籍『ユースケース入門 ユーザマニュアルからプログラムを作る』では、「ロバストネス分析」としてその意味や分析時に検討すべきことなどがまとめらています。それぞれ、英語、日本語訳といろいろな用語がありますが、この一連の記事では、オブジェクトを「バウンダリ」「コントロール」「エンティティ」の3つにまずは分解することをスタートポイントとします。

基本概念

『ユースケース入門』での解説では、バウンダリはユーザーなどユースケース上のアクタとの相互作用を行うオブジェクトで、画面、ダイアログ、メニューなどがそれに当たるとされています。エンティティは、ドメインモデルに基づくデータのデータを保持するオブジェクトや、あるいはテーブルなどのデータベースエンティティとのやりとりを行うものです。コントロールにはアプリケーションのロジックが実装されるものとされています。

この3つのオブジェクトの通信に関して、次の表のような取り決めがされています。なお、アクタはバウンダリへの通信は行いますが、逆にアクタへの通信という概念は考慮されていません。画面に表示することまでしかシステムとしてはできないという意味で解釈できると思います。それ以外は、要するに、コントロールはバウンダリやエンティティと通信できるけど、エンティティやバウンダリは、コントロールとの通信しかできないというルールです。バウンダリ-コントロール-エンティティという流れを定義することが、ユースケース上の表現を名詞-動詞-名詞のスタイルに揃える結果につながると書籍では説明されています。

From\To バウンダリ コントロール エンティティ
アクタ × ×
バウンダリ × ×
コントロール
エンティティ × ×

こうした記述がMVCパターンと同じような意図があるのではないかということは、まず感覚的にわかります[Mukhtar2004]。また、Model=エンティティ、View=バウンダリ、Controller=コントロールという対比をすれば、MVCとロバストネス図は、「同じような分類」を記述ルールに導入していると言えます。

ここでまず、MVCつまりMode-View-Controllerパターンを改めて紹介します。もともとは、Smalltalkでの対話型アプリケーション開発の問題点を克服可能なパターン[Krasner1988]として考案されたものです。F.ブッシュマン他の『ソフトウェアアーキテクチャ ソフトウェア開発のためのパターン体系』(いわゆる「POSA本」)でも、当初の定義に基づいて解説されています。図に示した通り、オブザーバーを介したやりとりが本来の定義です。コントローラはモデルを変更すると、その変更をオブザーバーによってビューに伝えられ、ビューがモデルにデータを取得するというものです。この点では、現在のWeb開発で使われているMVCと分類されるフレームワークと、対象としている動作そのものが違っていると言えるでしょう。しかしながら、本来の定義はさておいて、「モデルとビューとコントローラーに分離する」というアイデアが一人歩きした結果、現在のサーバーサイドでのWebアプリケーションフレームの基本的な形態としてMVCが存在するようになりました。

一方、Web系フレームワークでのMVCの発端は、Java2 EEの初期に提示されたMVC2と呼ばれるパターンがありますが、これはもともとJavaServer Pagesの仕様書にあった「JavaServer Pages Access Model 2」という記述から命名されています[Wikipedia – JSP Model 2 architecture]。そこでは、ユーザのリクエストを受け取るJavaServlet、データを管理するJavaBeans、表示するページを生成するJavaPagesといった図があり、それぞれ、Controller、Model、Viewであると言えなくもないことから、いつしかMVC2という用語で呼ばれるようになったものですが、Wikipediaの記述によると、誤解が重なった結果の用語がMVC2であると示されています。

一方、D.Alurらの著書『J2EEパターン』では、MVCパターンとしてのカタログ掲載はありません。現在のMVCと言われているものに近いものは、Application Controllerというパターンであり、そのView Handler戦略というパターンの1つの展開方法であると言えます。図は書籍に示された通りに清書したものですが、コントローラがデータを取得し、それをビューに渡して画面生成するという一般的なWebアプリケーションの動作そのものです。

MVC Definitions

以上のように、すでにカタログ化されているMVCパターン自体が多岐に渡っており、共通する点は、「データを扱うモデルと、画面周りのビューは分離して、別のオブジェクトに統括させる」というくらいであると言ってもいいのかもしれません。その意味では、これはロバストネス図の考え方そのものと言ってもいいでしょう。MVCパターンで構築するとよく言われますが、現在のWebアプリケーションでは、「MVCを基調とした考え方で設計されたフレームワーク」を使っている点で、すでにMとVとCに分離するという世界に取り囲まれることになります。設計時に、MVCをどの程度の意識すべきかは多様な意見があると思いますが、ロバストネス図上での荒い分類の上で作って、それを実装時に適切なクラス設計に落とし込むという考え方で進めれば、まずは必要な機能の洗い出しとその相互作用を書き込むということに集約できます。それが、MVCを基調としたフレームワーク上で実現できれば、その世界でのMVCパターンを一定水準以上満たした設計であると言えるでしょう。

実際にロバストネス図を記述してみます。なお、astah*で作成するときには、クラス図で記述すると、以下の図のようになります。この場合はクラス間の関連性しか記述はできません。以下の図が、astah*で作成できるロバストネス図に近い図と言えるでしょう。

MVC Server-Side (class)

一方、コミュニケーション図で記述すると、以下の図のように、オブジェクト間のメッセージのやり取りも記述できます。一連の記事で検討している開発プロセスでは、前記のクラス図ではなく、以下のコミュケーション図を主体にします。ICONIXのプロセスでは、クラス図によるロバストネス図の次は、シーケンス図を記述して、やりとりを記述します。しかしながら、シーケンス図はちょっとした図を記述するのにも、比較的労力がかかってしまいます。正確に記述でき、ほぼ、実装に直結した記述ができるのは良い点ですが、ここでも「他の図では自明なもの」をシーケンス図で記述することはしなくても良いと考えます。つまり、ロバストネス図にメッセージのやりとりを記載する、つまりコミュニケーション図として記述をすることで、一定の範囲の処理はシーケンス図に書くのと大きな情報量の違いはないと思われます。言い換えれば、1つのスレッドで順々に処理が進むものなら、シーケンス図でなくても十分に表現が可能と言えることです。ただし、クライアントとサーバーの間のやりとりや、並行プロセスの同期等が絡むような処理があるような場合には、他の図ではなく、シーケンス図上できちんと設計を進める方が良いでしょう。

MVC Server-Side (com)

前の図は、Webページでよくある動作パターンを、コミュニケーション図上のロバストネス図として記述したものです。検索条件入力画面が出ているとして、そこで条件を入れると、検索条件に合ったレコードが一覧されるというものです。もちろん、今時は懐かしい感じのUXではありますが、分かりやすい例として示しました。本来、アイコンは「オブジェクト」であり、矢印は「メソッド呼び出し」などの実装に直結するものになるまで分析しないと設計にはならないかもしれませんが、まずはそういう実装に関することを緩く考えれば、このような図でも間違いではないと思われます。

しかしながら、それでは「検索処理」というクラスを用意するのでしょうか?「顧客データ」というモデルクラスを用意するのでしょうか? もちろん、それでも可能ですが、一連のロバストネス分析でのアイコンすなわちオブジェクトと呼ばれているのは仮想的なオブジェクト、あるいはオブジェクトの断片と考えるべきであり、メッセージ送信はメソッドの候補的な考えの方が良いでしょう。想定するのは、例えば、システムにこうした機能が20個あれば、20個のコミュニケーション図が作成されるかもしれません。そこでの処理の流れや、エンティティの使われ方を俯瞰した上で、コントールやエンティティの実現するというように考えて、ロバストネス分析時点では、実装にあまり左右されない、あるいは引っ張られない抽象的な記述からスタートして詳細化することで、必要な機能のモデルへの注入がスムーズに行われることになります。

しかしながら、最後には実装しなければなりません。全体を俯瞰すると言っても、フレームワークの機能が全部やってくれる処理もあるでしょうし、設定を渡す必要がある箇所、あるいは全部自分で実装しないといけない箇所があります。しかしながら、「必要とされる機能」をいったんモデル上に記述した上で、フレームワークとの接点を考え、その上で実装を行うという方針で進めることで、スムーズな開発や、あるいは設計変更時の対処等も含めて、モデルの役割と実装への貢献がより高くなるのではないかと考えられます。

ユースケースをまずは記述し、そこからコミュニケーション図をベースにしたロバストネス分析を行って、システムが行うべき処理の詳細化を行います。そこまで分析を進めた上で、データベースのスキーマをエンティティを中心に検討し、その結果をもとにモデルクラスの設計へと移ります。一方、バウンダリやコントロールの機能をどのようにクラスとして最終的に表現するかとなると、ここは飛躍が大きすぎます。そのためには、バウンダリとコントロールだけでなくより詳細な書き込みを行いたくなります。また、詳細化するとなると、モデル上に表現したいのはオブジェクトよりも粒度の小さな「何らかの処理」の単位になってきてます。ただし、Web開発は様々なプラクティスが確立された、ある意味でパターン化された開発タスクの世界でもあります。何でも表現できるという点で抽象度の高いモデルの役割がありますが、ドメインに特化することで抽象度は下がってもそのドメインで有益なモデルの改良版は同様に役に立ようにできるでしょう。このモデルの表現をどのように拡張するのかの検討を引き続く記事で検討します。

クライアントサイドのパターンとの検討を次回に記述します。