アクティビティ図でアクティビティ要素の利用
はじめに
弊社のサポート窓口には、アクティビティ図でアクティビティ要素の利用について以下のような質問が定期的に届きます。
- クイックリンクでアクティビティ要素間(あるいはアクション要素とアクティビティ要素の間)にコントロールフローやオブジェクトフローの選択肢が出ない
- アクティビティ要素間にコントロールフローやオブジェクトフローを作成するとエラーになる
この動作、つまり、アクティビティ要素間にはコントロールフローやオブジェクトフローは作成できないことが正しいのですが、ツール、つまりEnterprise Architectが悪い(バグである)と誤解されている方が少なからずいらっしゃいます。
このページは、アクティビティ図にアクティビティ要素を配置している方に向けた説明ページです。
UMLの仕様における定義
まず、現在のEnterprise Architectの動作、つまりアクティビティ要素間にはコントロールフローやオブジェクトフローは作成できないということをUMLの仕様書の内容を参照して説明します。
まず、アクティビティ要素の定義は、UML2.5仕様書の15章で以下のように定義されています。図の中の「Activity」がアクティビティ要素です。
(このページの説明では、仕様書内の文字列は「Activity」のように括弧で囲みます。図は必要な部分のみを切り出していますので、図の全体は仕様書をご覧ください。)
この定義で着目すべき点は、コントロールフロー(「ControlFlow」)およびオブジェクトフロー(「ObjectFlow」)は共に「ActivityEdge」であり、「Activity」は「ActivityEdge」を所有(コンポジション・黒菱形の線)こそしていますが、入出力(「incoming」/「outgoing」および「source」/「target」)の対象ではありません。「ActivityEdge」の入出力の対象は、「ActivityNode」です。
次に、アクション要素(「Action」)の定義は、仕様書16.2.2に記載があります。以下の図です。
この図ではアクション要素は「ExecutableNode」であることはわかりますが、この「ExecutableNode」は最初の図には出てこないため、関係は不明瞭です。
この「ExecutableNode」と「Action」の関係は、仕様書15.5.2にある以下の図で示されています。
これらの情報をまとめると、「Action」は「ActivityNode」ですので、アクション要素の間にコントロールフローやオブジェクトフローは作成可能です。一方で、「Activity」は「ActivityNode」ではありませんので、アクティビティ要素間には作成できないことが確認できます。
これらのUML仕様書に記載の関係をトレーサビリティマップアドインを使って表示したものが下の図です。
アクティビティ要素とアクション要素の位置づけ
ここで、一般的なアクティビティ要素とアクション要素の位置づけ(使い分け)を紹介します。
例えば、業務を対象に考えると、アクティビティ要素は、ひとまとまりの「業務」であり、アクション要素は、1つ1つの具体的な「作業」に該当するような位置づけです。例えば、「請求書の発行」という業務があり、それをアクティビティ要素とする場合には、アクション要素は「請求書に必要な情報の収集」「請求書の作成」「請求書の印刷」「請求書の確認」「請求書の郵送」のような位置づけです。設計という観点では、アクティビティ要素は動作のシナリオ、アクション要素は機能、という位置づけになる場合もあります。
そして、アクティビティ要素1つに対してアクティビティ図1つを作成し、その中にアクション要素を配置するような関係になります。本来あるべき構造をEnterprise Architectのモデルブラウザで表現すると、以下のような形になります。
ただし、Enterprise Architectではアクティビティ図をアクティビティ要素の子ダイアグラムとして作成することを必須としていませんので、実際にはパッケージの直下にアクティビティ図を作成することが多いかと思います。そのため、パッケージを業務の単位で作成する場合など、アクティビティ要素は利用しないこともあります。
アクティビティ要素の使い方
それでは、アクティビティ要素はどのように使うのでしょうか。具体的には、ひとまとまりの業務を繰り返し使いたい場合や、業務間の流れを書きたい場合にはどうすればよいのでしょうか。こうした場合にアクティビティ要素をアクティビティ図に配置して、コントロールフローで接続して表現したくなるかと思います。しかし、アクティビティ図にアクティビティ要素が配置されることはありません。
アクティビティ要素(の内容)をアクティビティ図で使う場合には、振る舞い呼び出しアクション要素として利用します。モデルブラウザからアクティビティ要素をアクティビティ図にドロップすると表示される選択肢で、「アクション(呼び出し)」を選択することで、振る舞い呼び出しアクション要素を作成できます。振る舞い呼び出しアクションには、要素の右下にホウキのようなアイコンが表示されます。
ドロップしたアクティビティ要素が子ダイアグラムとしてアクティビティ図を持つ場合には、振る舞い呼び出しアクション要素をダブルクリックすることでその図を開くことができます。
なお、このページの内容も含めて、アクティビティ図での操作については以下のYouTubeの動画でまとめてあります。ぜひご覧ください。(4分24秒・音声あり)
既にアクティビティ要素をアクティビティ図に配置してしまっている場合、アクティビティ要素を右クリックして「追加設定」→「呼び出しアクションに変換」を実行することで、ダイアグラム上の要素を振る舞い呼び出しアクションに変換できます。アクティビティ要素はそのまま残りますので、必要に応じてアクティビティ図を作成し、その詳細を作成してください。
あるいは、単にアクティビティ要素をアクション要素に変更するだけであれば、プロパティサブウィンドウの「種類」欄の右端にある「...」ボタンを押し、「アクション」を選択してください。要素が多数ある場合には、スクリプトやアドインなどで一括変更する方が良いでしょう。
なぜ誤解が起きるのか?
最後に、なぜ「振る舞いを記述する目的で、アクティビティ図でアクティビティ要素を配置する」という誤解が起きるのか、を説明します。UML1.5までのバージョンではアクティビティ図にアクティビティ要素(正確にはActionState要素)を配置してフローでつなぐことは正しいことであったことが、最も大きな要因と考えます。そのため、長い経験を持つ方ですとUML2.0でも正しいと思い込んでいたり、あるいは過去に作成したモデルや書籍などでアクティビティ図にアクティビティ要素が配置されていたりします。
また、この誤解の原因の一端には、Enterprise Architect自身もあります。Enterprise ArchitectがUML2.0に対応した後も、互換性の確保の観点から、しばらくの間はアクティビティ要素間をクイックリンクでコントロールフローやオブジェクトフローを作成可能としていました。この挙動は、バージョン14.0で変更しUMLの仕様に準拠するようになりましたが、結果的に「UML2.0でもアクティビティ図にアクティビティ要素を置いても問題ない(=正しい)」という誤解を生んでしまったかもしれません。
また一方で、仕様に完全に厳密なのがよいのかどうか、という観点もあります。Enterprise Architectでは、仕様に反する内容でも記述できるようにしている面が少なからずありますので、結果的に仕様に反していることに気がつきにくくなります。UMLの教育用途のツールであれば厳密な方が望ましいですが、UMLなどの記法には限界があるため、現場で求められる設計内容を記載できない場合があります。その結果、それぞれの現場ごとの工夫が求められる面があります。このような状況を考慮し、Enterprise Architectは仕様に反する内容も記述できます。一方で、利用できる機能がそのすべてを考慮し対応することは困難ですので、多くの機能については、仕様に準拠していることを想定しています。
互換性の確保や厳密性と自由度の兼ね合いというのはなかなか難しい問題で、今後も利用者の利便性と仕様への準拠との両方を考慮しながら、ツール提供ができればと考えています。
どうしても、アクティビティ要素をアクティビティ図で使いたい場合
上記の内容を踏まえた上で、何らかの理由で(仕様違反だとしても)アクティビティ要素をアクティビティ図に配置して、コントロールフローやオブジェクトフローを利用したい、という場合があるかもしれません。その場合には、以下の3点を踏まえてご利用ください。
- ユーザーのオプションの「接続」グループにある「作成時に文法をチェックする」のチェックボックスを外してください。この設定が有効な場合、仕様違反の接続を作成できません。
- クイックリンク機能は使えません。ツールボックスから接続を作成してください。ツールボックスからの作成の場合で上記の「作成時に文法をチェックする」が無効の場合には、仕様を無視して接続を作成できます。
- Enterprise Architectやアドインの機能で考慮・対応していない場合があります。仕様に反する内容に対応していない点が問題となる場合には、仕様に準拠するようにモデルを作成してください。あるいは、独自にアドインを作成し、自分たちのモデルに対応する機能を作成するという方法もあります。