ソフトウェア開発の分析/設計段階ではシステムをモデル化して表現する。ただ,システムを完璧に表現できる万能なモデルは存在しない。さまざまなモデル要素から適切なものを選択し,上手に組み合わせることが必要だ。モデルを適切なアーキテクチャにマッピングする際は,アーキテクトが重要な役割を担う。

(本誌)

図1●分析モデルの例
一人の顧客は0以上の購入注文を出す。1件の購入注文には1以上の商品の種類とその個数の指定があり,注文明細として示されている。図中の箱は業務上のデータの意味のまとまりを,箱と箱の間の関係はデータ間の汎化と特殊化,全体と部分,役割,ルールや制約などを示す。人間は同一の線をさまざまな意味でとらえる。

 ソフトウェアの最終的な成果物は実行可能なプログラムである。しかし高度で複雑化した技術が求められたり,開発規模が大きい場合には,いきなりプログラム開発に取りかかるのは危険が大きい。システム化すべき問題を明確にして適切な仕様を決め,確実に実装することが困難になるからだ。このためソフトウェアの仕様化,つまり分析/設計モデル(以下,単にモデルという)の導入を考えなければならない。

 ただしあらゆる問題に対処できる万能なモデルは存在しない。このためソフトウェア開発の進歩に伴い,多様なモデルが生み出され,使い分けられてきた。現在ではオブジェクト指向分析/設計が主流となり,UMLによるモデル記述が一般化している。しかしそれで問題が完全に解決するわけではない。そもそも完全さを一つの技術に求めるべきでもない。

モデルはさまざまな意味を持つ

 優れたモデルは,システムの任意の見たい部分が分かりやすく表現されている。そのためには仕様が十分に理解され,しかも正確で一貫性を持って表現してある必要がある。

 このとき,モデルにシステムの完全な表現を求めてはならない。モデルを必要以上に詳細に書くと,分かりにくくなったり,作成に時間やコストがかかり過ぎたりする。

 また,モデルはさまざまな意味を持ちうる。システムを2次元の箱と,箱と箱の間を結ぶ線で表現する場合,箱が何を意味するかはモデルを作成した人の意図により異なる。箱,すなわちモデル要素の意味により,その間に引かれた線などの持つ意味は変わる。モデル要素の意味は,さまざまな要因から決定される。モデルのスコープ,抽象レベル,粒度,動的と静的の視点などである*1

 例えばクラス。クラスは,システムの静的構造を表現するモデル要素である。クラスの抽象レベルと粒度,クラス間の関係などには複数の意味が考えられる。業務領域とシステム領域によって粒度が違うのはその一例だ。

 もう少し具体的に見てみよう。例えば業務領域のモデルに,商品クラスがあったとする。これが注文クラスと関係を持つと,その注文で売れた商品という意味になる(図1[拡大表示])。商品の注文処理という業務上のスコープに基づいて考えるので,商品クラスや注文クラスは業務上一つのデータのまとまりとして認識される。

 システムの実装技術を考えると,さらにモデルの意味が変わる。実装時には,モデルをデータ構造やプログラム構造に対応付ける。このとき,必ずしも業務領域の意味のまとまりと同じ単位で扱う必要はない。商品クラスはリレーショナル・データベースのテーブル,注文クラスはWebサーバー上のスクリプト言語で実装されるデータとプログラムとなる。別の実装ではXMLメッセージやオブジェクト指向言語のクラス定義になるかもしれない。つまり実装時には,システムをどのようなアプリケーションとするかがスコープとなる。Webアプリケーション,XMLメッセージ交換アプリケーションなどを適用する。その抽象レベルはフレームワークや開発言語が決定する。

モデル要素を発明して問題解決

 人間に理解しやすいモデルを作成するのは容易ではない。人間は,モデル要素の箱の配置や線による関係付けの様子から,システムの複雑さや一貫性を見てとる。人間の認識能力は単純で小規模な2次元図形に限られる。このため,抽象レベルを変化させ,粗い粒度の表現と詳細な粒度の表現を組み合わせたり,動的側面を別の表現法で補足する必要が生じる。

 しかし複数の表現法を導入すると,表現法同士の関連や一貫性の検証が複雑になる。そのためにソフトウェア開発者は絶えず,モデル表現法の洗練化や新たなモデル要素の開発に取り組んできた。

 代表的なモデル要素には,静的モデルのクラス構造と,動的モデルのシーケンスや状態遷移などがある。しかしこれだけでは解決できない問題もある。こうした問題に対処するために発明された新たなモデル要素には,フィーチャ,インタフェース,アスペクト,ユースケース,モジュールなどがある*2

 これらはいずれも2次元の箱と,箱と箱の間を関係付ける線で描かれることが多い。しかし解決すべき問題領域が異なるので,それぞれが特徴的な意味を持つ。具体的に,(1)フィーチャ,(2)モジュール,(3)ビジネスルール,(4)ロール,(5)プロセス,(6)エンティティ,(7)サービスの7種類を順に見ていこう。

クラス横断的に機能を実現

 (1)のフィーチャは,システムのユーザーが実際に目にする機能を表現する。一般に,複数オブジェクトが連携して一つの機能を実現する。従って一つのフィーチャを追加しようとすると,新たな実装クラスを追加するだけでなく複数の既存実装クラスへの変更を伴う。必然的に,フィーチャはクラスに横断的な性質を持つ。

 フィーチャは,各クラスが受け持つ責任の一部の機能を表現する「インタフェース」(具体的にはIDL:Interface Definition Languageによる定義など)よりも粒度が大きい。最近注目を浴びるアスペクト指向は,クラス横断的な性質を持つフィーチャをプログラムの静的な構造を変更することなく設計し実現するための考え方である。なお,ユーザーとシステムの相互作用でフィーチャの実現方法を表現するユースケースは,フィーチャ表現法の一種である*3。フィーチャとユースケースはシステムの機能だけに限定されず,それを利用する顧客やアクターに対する価値も定義する。

クラス以外の単位で差分を管理

 フィーチャを追加する際に必要となるのが(2)のモジュールである。フィーチャの追加による変更分をまとめ,複数の実装クラスにまたがった差分を管理する。従来,オブジェクト指向はクラス実装の継承機構を使い,クラス単位で差分を管理してきた。しかし最近では,クラスを単位としない保守管理技術も必要である。クラス実装コードの大半が開発ツールなどにより自動生成されるからだ。自動生成コードと開発者が開発したカスタムコードが同一ソースコードに混在すると,保守で問題が生じる。両者の変更管理を独立させておきたい。そこでモジュールを使って,1クラスを複数のソースファイルで定義したり,複数クラス定義やその変更分を一つのソースで管理する*4

特定の制約をビジネスルールで表現

 (3)のビジネスルールは,実世界の業務などで特定の目的のために課される要件や制約である。1クラスの属性や状態の制約,複数クラス間にまたがる関係への制約で表現する。例えば「危険防止のために,1000時間ごとに機械を点検しなければならない」というビジネスルールは,機械クラスと点検クラス間の関係に対する制約で表現される。実装時には,オブジェクトの状態遷移が起こる時にビジネスルールをチェックすることになる。

場面に応じて役割が変わる

 (4)のロールは,クラスの役割の変化を表現するモデル要素である。ロールを導入することにより,クラスが場面に応じて役割を変える状況を記述できる。役割が変わるときには,その都度クラス実装継承を使い別のサブクラスを定義してもよい。しかしロールを使えば,基底クラスの汎用性,アプリケーションに依存しない独立性,再利用性の向上を確保できる。

 例えば商品クラスは,サプライ・チェーンにおける販売と製造では粒度が異なる。販売における商品クラスは商品コード,商品名,価格,製造年月日などで定義される。しかし製造における商品クラスは,製造所,製造ライン,ロット番号などの追加情報が必要である。販売の商品クラスより粒度が大きく詳細である。この二つを共通の商品クラスで表現し,ロールでその差を吸収する。顧客クラスなど人間系クラス(パーティと呼ぶこともある)の汎用性を高めるには,もっと多くのロールが必要である。取引先やセキュリティ権限者などがその一例である。

サブシステムを組み合わせる

 (5)のプロセスは,複数のサブシステムを組み合わせてシステムを実装するための,ワークフローの定義である。サブシステム同士を連携させたり,サブシステム内の処理の流れを制御したりする。プロセスはプログラム動作と同じ,繰り返し,条件分岐と結合,例外などを持つ。プロセスを使って設計されたシステムは,複数プロセスが同時並行に動作する一種のトランザクション・システムである。現在主流であるアプリケーション・サーバーなどコンポーネント・ミドルウェアによる開発は,インタフェースとクラスの定義を中心とした開発である。しかし開発環境の高度化により,状況が変わり始めている。主に業務系やサービス指向アーキテクチャ(SOA)の開発で,プロセスと後述するエンティティを中心とした開発に移行しつつある。

データと振る舞いを併せ持つ抽象データ型

 プロセス内では,しばしばデータへのアクセスが発生する。このデータを表現するのが(6)のエンティティだ。実装ではなく業務上の意味に基づいて作成されるオブジェクトの一種である。モデルの作成時には,データの業務上の意味とそのシステム上の実装表現を分離する。このうち業務の作業手順に必要な業務データ(概念モデル)と,その必要な振る舞いを合わせた抽象オブジェクトがエンティティである。つまりエンティティ-リレーションシップ(E-R)におけるエンティティとは,厳密には意味が異なる。E-Rにおけるエンティティはデータの器である。これにデータの操作や制約を加え,抽象データ型として扱ったものがここで言うエンティティと考えてよいだろう。

 エンティティに似たものに論理データモデルがある。論理データモデルは永続化が必要なデータの構造であるが,エンティティは必ずしも永続化を必要としない。またデータだけでなく振る舞いを持つ実装非依存なオブジェクトで,実行時にプロセスと関連付けられる。

 エンティティを導入することにより,同一の業務データをさまざまなシステムにあわせて実装できる。オブジェクト指向言語クラス定義やコンポーネント・モデル,関係データベース・テーブル定義,XMLスキーマ定義,メッセージ・データ形式などである。

サービスは実装技術に依存しない

 エンティティと同じく,実装技術に依存しない機能の提供をモデル化するのが(7)のサービスである。SOAにおいて用いられる。サービスを利用する場合のメッセージ型と,その際にどのようなメッセージを交換するかによってサービス契約を表現する。また,サービス識別,呼び出し形式,アクセスに必要なバインド情報をインタフェース定義とする。一般にWSDL(Web Services Description Language)を使って記述する。これらは,サービスを構築する実装技術とは独立して定義される。