アジャイルモデリング(AM)
公式サイト
モデリング成果物>UML 2 シーケンス図

UML 2 シーケンス図の概要

by Scott W. Ambler, Copyright 2003

UMLシーケンス図を使うことで、システム内のロジックの流れを視覚的に表現し、ロジックを文書化して検証できます。この図は一般的に、分析にも設計にも使われます。システム内の振る舞いを明らかにするための動的モデリングを行うときには、UMLの成果物の中でもシーケンス図をもっともよく使用します。動的モデリングの技法にはこの他に、アクティビティ図コミュニケーション図タイミング図相互作用概観図などがあります。私の意見ですが、最新のビジネスアプリケーション開発を行うときにもっとも重要になる設計レベルのモデルは、このシーケンス図と、クラス図物理データモデルです。

通常、シーケンス図は以下のものをモデリングするために使います。

  1. 利用シナリオ:利用シナリオとは、考えられるシステムの使い方を記述したものです。利用シナリオのロジックは、ユースケースの一部(もしかしたら代替コース)かもしれません。アクションの基本コースに記述されるロジックのようにユースケース全体にわたるものかもしれませんし、アクションの基本コースの一部かもしれませんし、代替シナリオも含まれているかもしれません。あるいは、利用シナリオのロジックは、複数のユースケースにまたがるロジックを通るパスの可能性もあります。たとえば、ある学生が大学に登録し、そのまま続けて3つのゼミに登録するといった具合です。

  2. メソッドのロジック:シーケンス図を使って、複雑な操作や関数やプロシージャのロジックを調べることができます。シーケンス図(特に非常に詳細なもの)は、視覚的に表現したオブジェクトコードだと考えることができます。

  3. サービスのロジック:サービスとは事実上、高いレベルのメソッドであり、たいていはさまざまなクライアントから呼び出すことができます。サービスにはWebサービスやビジネストランザクションなどがあり、これらはCICS/COBOLやCORBA準拠のオブジェクトリクエストブローカー(ORB)などのさまざまな技術を使って実装されます。

では、3つの簡単な例を見てみましょう。図1「大学に登録する」のユースケースのシーケンス図で、アクターとシステムとの相互作用をシステムレベルで示しています。図2は、申込者がすでに大学に登録した学生かどうかを判断するサービスの詳細ロジックを表すシーケンス図です。図3はゼミに登録するためのロジックを示しています。私はたいてい、利害関係者と一緒にシステムレベルのシーケンス図を作成し、利用シナリオのロジックを目に見える形に表現して検証するために使っています。また、申込者がすでに学生として存在するかどうかの確認など、システムがサポートしなければならない重要なメソッドやサービスを識別するのにも役立っています。

 

図1 システムレベルのシーケンス図

 

これがシーケンス図と呼ばれている理由は明らかでしょう。ロジックの実行順序(シーケンス)がメッセージ(横向きの矢印)の順序で示されています。最初のメッセージは左上から始まり、次のメッセージはそのすぐ下に書く、というように表していきます。

 

図2 サービスレベルのシーケンス図

 

図の上部に横に並んでいる箱は、分類子またはそのインスタンスを表します。この分類子は通常、ユースケース、オブジェクト、クラス、またはアクターです。オブジェクトとクラスにはメッセージを送ることができるため(オブジェクトは操作の呼び出しを通じて、クラスは静的操作の呼び出しを通じてメッセージに応答します)、これらをシーケンス図に含めるのは筋が通っています。アクターも、利用シナリオを開始したり、利用シナリオで能動的な役割を果たすので、シーケンス図に含めることができます。オブジェクトにはUML標準の「名前: クラス名」という書式でラベルをつけます。この名前は必須ではありません(図で名前の付いていないオブジェクトのことを無名オブジェクトと呼びます)。クラスには「クラス名」という書式でラベルを付け、アクターには「アクター名」の書式で名前を付けます。オブジェクトのラベルには下線が引かれていますが、クラスとアクターには引かれていないことに注意してください。たとえば、図3の学生オブジェクトにはある学生という名前が付けられています。これが名前付きオブジェクトです。それに対してゼミのインスタンスは無名オブジェクトです。Studentのインスタンスに名前が付けられているのは、複数の場所でメッセージのパラメータとして使われているためです。ゼミのインスタンスの方は、図の他の場所で参照する必要がないので、無名にしておくことができます。図2では、学生クラスが永続性フレームワーククラスにメッセージを送っています(永続性フレームワーククラスには<<infrastructure>>というステレオタイプを付けてもよかったのですが、図を簡潔にしておくために付けませんでした)。クラスに対して送られたメッセージは、すべて静的メソッドとして実装します。これについては後で説明します。

 

図3 ゼミに登録する(メソッド)

 

箱からぶら下がっている点線はオブジェクト生存線と呼ばれるもので、モデリング対象のシナリオの期間におけるオブジェクトの寿命を表します。生存線上の細長い長方形は活性区間、あるいはメソッド呼び出し区間 (method-invocation box) と呼ばれるもので、受け手のオブジェクトまたはクラスがメッセージの処理を行っていることを表します。私が活性区間を使うのは、高機能のCASEツールなど、もともとそれをサポートしているツールを使っているときと、パフォーマンスの問題について考えたいときだけです。ホワイトボードや、簡単に書けるようサポートしていない描画ツールで書くには、活性区間はあまりに面倒です。

活性区間の下の端にある×(図4の例を参照)は、オブジェクトがメモリから削除されたことを表すUMLの慣例です。C++など自分でメモリを管理しなければならない言語では、オブジェクトのデストラクタを呼び出す必要があります。デストラクタは通常、<<destroy>>というステレオタイプの付いたメッセージとしてモデリングします。JavaやC#など、メモリ管理機能が備わっていて、必要なくなったオブジェクトは自動的にメモリから消されるような言語では(この機能を通常はガベージコレクションと呼びます)、このメッセージをモデリングする必要はありません。私は通常、オブジェクトのデストラクタはモデリングせず、このような低レベルの詳細はプログラマ(たいていは私自身)が実装してくれると信用することにしています。

図4は、「ゼミに登録する」ユースケースのアクションの基本コースを表した、複雑なUMLシーケンス図です。これは、利用シナリオのロジックをモデリングするための選択肢の1つです。図1のようにシステムレベルで記述するのではなく、いきなりオブジェクトレベルで詳細ロジックをモデリングします。シーケンス図に慣れた開発者と仕事をしている場合や、大きな作業スペース(巨大なホワイトボードや、大きな画面と優れたグラフィックスカードを備えたワークステーションにインストールしたCASEツール)がある場合には、私はこのアプローチを採用します。しかしたいていは、まずシステムレベルの図を書き、それから図2図3のような小さな図を作成します。

 

図4 「ゼミに登録する」ユースケースのアクションの基本コース

== Enroll in Seminar: ゼミに登録する Basic Course of Action: アクションの基本コース SD#: UC17-01: シーケンス図 UC17-01 1. Student indicates wish to enroll: 1. 学生は登録したいと思っていることを示す 2. Student inputs name and number: 2. 学生は名前と番号を入力する 3. System verifies student: 3. システムは学生を確認する 4. System displays seminar list: 4. システムはゼミ一覧を表示する 5. Student picks seminar: 5. 学生はゼミを選択する 6. System determines eligibility to enroll: 6. システムは登録資格があるかどうかを判断する 7. System determines schedule fit: 7. システムはスケジュールに問題がないことを確認する 8. System calculates fees: 8. システムは授業料を計算する 9. System displays fees: 9. システムは授業料を表示する 10. System verifies student wishes to enroll: 10. システムは学生が登録したいと思っていることを確認する 11. Student indicates yes: 11. 学生は「YES」と意思表示する 12. System enrolls student in seminar: 12. システムは学生をゼミに登録する Note: Need to flesh this message out more.: メモ: このメッセージはさらに肉付けする必要がある ==

UMLシーケンス図のメッセージはラベルの付いた矢印で表され、メッセージを送る側と受ける側がオブジェクトやクラスの場合には、そのラベルはメッセージに応答して呼び出されるメソッドのシグニチャになります。しかし、送る側または受ける側のいずれかが人のアクターの場合には、メッセージのラベルは、伝えられる情報を記述した短いテキストになります。たとえば図4で、ゼミ登録オブジェクトは登録資格があるか(登録対象の学生)というメッセージをゼミのインスタンスに送信しています。このメソッドの名前と渡されるパラメータ(あれば)の名前の両方を表示していることに注意してください。学生アクターはセキュリティログオンオブジェクトに、名前および学生番号というラベルの付いたメッセージによって情報を提供します(実際にはこれらはメッセージではなく、ユーザの相互作用です)。

返り値は必須ではありませんが、返り値を表すラベルの付いた破線の矢印で表すことができます。たとえば、メッセージを呼び出した結果として学生クラスから登録対象の学生という返り値が戻ってくることが示されていますが、ゼミに登録資格があるか(登録対象の学生)メッセージを送った結果の返り値は示されていません。私は、何が返されるかが明白な場合には、シーケンス図が乱雑にならないよう、返り値を書かないことにしています(見れば分かるように、シーケンス図はすぐに複雑になってしまうからです)。図5は、返り値を示す別の方法を表したものです。メッセージの場合には「message: returnValue」という書式を使います。たとえば「登録資格があるか(登録対象の学生): false」といった具合です。

図全体でステレオタイプが使われていることに注目してください。長方形の中には、アクター、コントローラクラス、ユーザインターフェース(UI)クラスを表す<<actor>>、<<controller>>、<<UI>>というステレオタイプを適用しています。また、図によってはステレオタイプのアイコンを使用します。アクターを表す人型のアイコンや、ロバストネス図のコントローラ、インターフェース、エンティティの各オブジェクトを表すステレオタイプのアイコン、データベースを表す円筒などです。ステレオタイプはメッセージにも付けることができます。UMLの図で一般的に行われるのは、生成および消滅を表すメッセージに<<create>>および<<destroy>>のステレオタイプを付けることです。たとえば、セキュリティログオンオブジェクトはこのようにして生成されています(実際にはおそらくこのメッセージはクラスに送られ、その結果生成されたオブジェクトが返り値として返されることになります。つまり少しごまかしているわけです)。このオブジェクトはその後、おそらくはウィンドウが閉じられたときに、同じように自分自身を消滅させます。

図4ではUMLのノートを使っています。ノートとは基本的に自由形式のテキストで、任意のUMLのダイアグラムに置くことができます。この図ではヘッダとしてタイトルと識別番号を表しています(もうお気づきでしょうが、私は残しておくつもりのあらゆる成果物に一意の識別番号を付けています)。ノートは、右上を折り返した紙の形で表します。この図では、今後、分析あるいは設計時に行わなければならない作業を表すのにもノートを使っています。おそらく受講資格()メッセージは学生オブジェクトに送られる一連のメッセージを表しているからです。UMLでは一般的に、破線を使ってノートを別のモデリング要素に結び付けます。この場合、ノートはメッセージに結び付けられています。

図4では「ゼミに登録する」ユースケースのアクションの基本コースのロジックをモデリングしていますが、代替コースはどのようにモデリングすればよいのでしょうか。一番簡単な方法は、図5のように、代替コースごとにシーケンス図を1つ作成することです。この図では代替コースのロジックだけをモデリングしています。これは図の左端に書かれたステップの番号を見ても分かりますし、図のヘッダとなっているノートにもこれがアクションの代替コースであることが書かれています。また、この図のIDから、これが代替コースCだと分かるようになっていることにも注目してください。これは私が長年の経験から役に立つと気づいた方法です。

 

図5 「ゼミに登録する」ユースケースのアクションの代替コース

 

シーケンス図のその他の表記法について見ていきましょう。図5には、黒丸で示された「学生がゼミを選択する」という初期メッセージが含まれています。これはメソッド呼び出しの形でも簡単に示すことができます(おそらく「登録する(ゼミ)」のようになるでしょう)。図6にはオブジェクトの生成を表す別の方法が示されています。クラスに対してnewメッセージを送っているのです。これでオブジェクトの生成を表現する方法を3つ紹介しました。他の2つは、<<create>>というステレオタイプの付いたメッセージを送信する方法と、分類子のシンボルの側面にメッセージを送る方法(たとえば図4ではゼミ登録の側面に、図6では学生情報ページの側面にメッセージが送られています)です。どれか1つを選択して、それだけを使うようにしてください。

図6および図7には、ループのロジックを表す方法が示されています。1つは、「loop」というラベルと何がループ処理の対象になるかの制約(図6の[for each seminar]など)の付いたフレームを使う方法です。もう1つは、何度も呼び出されるメッセージの前に単に * (星印)を付ける方法です(図7の「ゼミに登録する」ユースケースを包含している部分を参照してください)。

 

図6 成績証明書の出力

 

図6にはシステムプリンターへの非同期メッセージが含まれていて、半分の矢じりで表されています。非同期メッセージとは、送る側がメッセージの結果を待たずに、返ってきたときに(返ってきたら)結果を処理するメッセージのことです。これまでのメッセージはすべて、結果を待ってから先に進む同期メッセージでした。ハードウェアデバイスやメッセージバスなどの自律的ソフトウェアサービスには、非同期メッセージを送るのが一般的です。

図7で使ったユースケースを包含(include)するモデリング方法は、私が『The Elements of UML Style』で最初に提案したものですが、他の人もこの方法を使っているはずです。基本的に、ユースケースの楕円は、他の分類子と同じように図の上部に並べて置き、そこに送られるメッセージに<<include>>のステレオタイプを付けます。これはユースケース図やシーケンス図を作成するときの方法と同じです。

 

図7 大学に登録する

== Applicant Regstration: 申込者登録 UC17 Enroll in Seminar: ゼミに登録する [applicant on eligibility list]: [申込者が有資格リストに載っている] Student: 学生 Name: 名前 Address: 住所 Phone: 電話 Application Screen: 申込みスクリーン ==

もう1つ図7で興味深いのは、条件ロジックのモデリング方法が示されている点です。この場合、「alt」というラベルのついた枠 (frame) にガード条件([申込者が有資格リストに載っている])を付けて表しています。枠は破線で区切られます。ここでは選択肢ごとに2つに区切られていますが、必要なだけいくつにでも区切ることが可能です(case文を図で表せるようになっています)。区切られた領域ごとにガードを付ける必要があります。

 

シーケンス図を使ったビジュアルコーディング

以前にシーケンス図とは事実上ビジュアルコーディングの1つの形態だと述べましたが、シーケンス図を使って非常に詳細な設計ができると考えることも可能です。図4のシーケンス図を作成したときに、私は、他のモデルに影響を及ぼす可能性のある決定をいくつか行っています。たとえば、ステップ10をモデリングしたときに、授業料が許容範囲内にあることを学生に確認させる処理を授業料表示画面で行うという決定を行いました。

また、ステップ2および3をモデリングしたときに、私は学生がシステムを使うときにおそらくパスワードが必要だろうと気付きました。AMの「利害関係者の積極的な参加」および「他の人と一緒にモデリングしよう」のプラクティスに従っている場合には、このような考えが妥当かどうかを確認するのは簡単です。尋ねればいいだけだからです。この場合は私が間違っていることが分かりました。この目的には名前と学生番号だけで十分で、大学ではパスワードの管理のために処理を複雑にしたくなかったのです。この興味深い決定事項は大学の運用方針なのでビジネスルールとして記録しておくとよいでしょう。つまり、記録に残したい場合には、「他の成果物に移ろう」のプラクティスに従ってそのルールを書きとめておく必要があるということです。

 

シーケンス図の書き方

私は何年もシーケンス図の書き方を人に説明してきましたが、その過程で気付いたのは、それを理解できた人は、論理的な考え方が非常に得意か、ソフトウェアコードを書くのが得意だということです。シーケンス図は、システムレベルのシーケンス図で利用シナリオをモデリングしている場合も含めて、事実上ビジュアルコーディングなのです。

私がシーケンス図を作成するときには、まず何をモデリングするかの範囲を明確にします。AMの「少しずつモデリングしよう」のプラクティスに従おうと思っているため、通常は、システムレベルの小さな利用シナリオか、詳細なオブジェクトレベルの1つのメソッドまたはサービスを対象にします。私の経験から言うと、図4のような図は複雑すぎて役に立ちません。

その後、少なくとも別の1人の人と一緒に、必要になれば上部に分類子を追加しながらロジックを書いていきます。私は無意識にオブジェクト生存線を書き加えますが、すでに述べたように通常は活性区間の箱を追加するのに時間をかけることはしません。この図でもっとも重要なのはメッセージなので、ロジックを追いながら1つずつメッセージを追加していきます。返り値を書くことはほとんどありません。メッセージに分かりやすい名前を付けておけば、たいていは何が返されるかが明らかになるからです。

面白いことに、シーケンス図を作成していると、クラスやオブジェクトの新しい責務が見つかったり、ときには新しいクラスが見つかることもあります。これは、それに合わせてクラス図を更新する必要があるかもしれないということです。アジャイルモデリングでは「複数のモデルを並行して作ろう」のプラクティスに従いますが、この作業はCASEツールが自動的に行ってくれるかもしれません。クラスに送られるメッセージはどれもそのクラスの静的メソッド/操作を呼び出し、オブジェクトに送られるメッセージはどれもそのオブジェクトの操作を呼び出すということを忘れないでください。

シーケンス図のスタイルの問題に関しては、私はメッセージを左から右に、返り値を右から左に書くようにしています(ただし、複雑なオブジェクトやクラスの場合には必ずしもそうできるわけではありませんが)。メッセージのラベルや返り値は、矢じりにもっとも近くなるよう近くに揃えて置きます。また、シーケンス図は左から右に階層 (layer)に分けるようにしています。まずアクターを、それからコントローラクラスを、そしてユーザインターフェースクラスを、最後にビジネスクラスを置きます。設計時にはたいていシステムクラスや永続化クラスを追加する必要がありますが、それは通常、シーケンス図の一番右端に置きます。このように階層に分けてシーケンス図を書くことで、多くの場合、図が読みやすくなり、また、ユーザインターフェースクラスが永続化クラスに直接アクセスしているなどといった階層のロジックの問題が見つかりやすくなります。

 

アジャイルさを保つ

実行に際してもっとも重要なことは、内容の面でも道具の面でも図を簡潔にしておくことです。ユースケースのロジックの検証やメソッドあるいはサービスの設計など、何かをじっくり考えるときには、私はホワイトボードにシーケンス図を書きます。シーケンス図の本当の価値はそれを作成すること自体にあると気付いたので、図を残しておくことはほとんどありません。

よく見られる間違いは、システムのあらゆるシーケンス図を作成しようとすることです。以前に見たプロジェクトチームでは、何ヶ月もかけて、アクションの基本コースに1つ、代替コースごとに1つずつと、ユースケースごとにいくつものシーケンス図を作成していました。シーケンス図を作成するのは、複雑なロジックについてじっくり考えたいときだけにすることを推奨します。ロジックが簡単であれば、シーケンス図を作成してもあまり意味はありません。直接コードを書けばよいのです。

 

 

 

注: この成果物の説明は『The Object Primer 3rd Edition: Agile Modeling Driven Development with UML 2』より抜粋しました。


推奨文献

 

その他の文献

アジャイルモデリング(AM)について詳しく知るにはこの本をお薦めします。

 アジャイルモデリング

 

Let Us Help (以下、北米での話ですのでご注意ください)

Ronin International, Inc. continues to help numerous organizations to learn about and hopefully adopt agile techniques and philosophies.  We offer both consulting and training offerings.  In addition we host several sites - Agile Modeling, Agile Database Techniques, UML Modeling Style Guidelines, Enterprise Unified Process (EUP) - that you may find of value.

You might find several of my books to be of interest, including The Object Primer, Agile Modeling, The Elements of UML Style, and Agile Database Techniques.

For more information please contact Michael Vizdos at 866-AT-RONIN (U.S. number) or via e-mail (michael.vizdos@ronin-intl.com).

 

visits since June 8, 2004.