シーケンス図の中に登場するオブジェクトは以下の形式のテキストで表現されます:
<名前>:<タイプ>[<フラグ>] "<ラベル>"
もうひとつは以下の形式になります:
/<名前>:<タイプ>[<フラグ>] "<ラベル>"
これらのテキストを、テキストエリアの中で入力していきます。<タイプ>という型を持ち、<名前>を持つインスタンスが生成され、ライフラインとしてみることができます。[<フラグ>]と"ラベル"はオプションになります。
引用符でくくられたラベルを設定すると、オブジェクトのラベルとして使用されます。設定しなかった場合には、名前とタイプ名から構成されたラベルが使用されます。
もしも<名前>の前に'/'をつけると、ライフラインが見えなくなります。この<名前>オブジェクトに対して、'new'メッセージが送信されると初めてライフラインが表示されるようになります。詳細は後で述べます。
オブジェクト宣言の後ろには、角括弧で囲んで、フラグをいくつか書くことができます。a, p, r, xの4つのフラグがサポートされています(訳注:5つあるが?):
オブジェクトを無名に設定します。図の中で名前が表示されなくなり、タイプ名との境目となるコロン(:)より後だけになります。ただし、ライフラインの指示で必要なため、テキスト表現の中では仮の名前を設定する必要があります。このフラグは、<ラベル>が指定された場合には無効になります。
ライフラインのラベルにアンダーラインが付かなくなります。
オブジェクトはアクターのように振舞います。ただし、人の絵ではなく、太枠で囲まれたボックスとして表現されます。
プロセスのみ外部と宣言をすることができます。これを宣言すると、"found"メッセージを送信することが可能な、外部のエンティティになりますが、図の中には表示されなくなります。外部プロセスから来るメッセージは、塗りつぶされた円で始まる矢印として表現されます。
オブジェクトは最後の返答をしたあとに破棄されるようになります。破棄はライフラインの最後にバツ印が付くことで表現されます。これは、ガーベジコレクタによって、非永続オブジェクトが自動的に破棄されたという風に解釈ができます。
これら以外にも、マルチスレッドに関するフラグがいくつかあります。
もし<タイプ>として'Actor'が指定されると、ライフラインはアクターに属すようになります。アクターは常にアクティブで、非同期にメッセージを送ることができます。自分自身にメッセージを送ることはできません。当然、返信を受け取ることもできません(以下参照)。アクターに対して返信を送る場合には、明示的なメッセージを使用する必要があります。
メッセージセクションの行は、以下のようなフォーマットで記述します
<呼び出し元>[<s>]:<返信>=<呼びだし先>[m].<メッセージ>
<呼び出し元>はオブジェクトセクションで定義済みのオブジェクトの名前を指定します。このオブジェクトは、最初にメッセージを送信するケースと、メッセージを受け取っているが、まだ返事を返していないという両方のケースでも記述することができます。アクティブになっていない場合にはメッセージを送信することはできません。[<s>]はオプションの引数で、呼び出し元オブジェクトの定義を詳細化します。
もしも<s>に数値が指定された場合には、呼び出し元の’レベル’を意味します。呼び出し元オブジェクトはk個のメッセージを受け取ります。このとき、<s>には0~k-1までの数値を入れることができます。<呼び出し元>がメッセージを送る前に、最近の<s>個のメッセージに対して答えるようになります。
ノート
(訳注)以下の二つのスクリプトを入力して比較してみてください。
(A)パターン:
a:A
b:B
a[2]:a.test
a[0]:b.call
(B)パターン:
a:A
b:B
a[2]:a.test
a[1]:b.call
1を入れると、ネストを一段戻ってからメッセージを送付していることが分かります。
<s>が数値でなかった場合には、ニーモニックとして扱われます。ニーモニックは呼び出し先に対して、オプションの[<m>]部を利用して定義されます。もしも<s>が<呼び出し元>オブジェクトに対して定義されており、<呼び出し元>がアクティブの場合には、<呼び出し元>[<s>]はこのオブジェクトを参照します。
<answer>=はオプションのパラメータです。<answer>には、メッセージの返り値に関する、シンプルな文字列表現を入れます。
<呼び出し先>.はオプションで、<呼び出し先>は文字列形式の<メッセージ>を受け取るオブジェクトをあらわします。<メッセージ>は、<呼び出し元>から<呼び出し先>に対して作成される矢印のラベルとして使用されます。もしも<呼び出し先>が指定されなかった場合には、呼び出し元自身が実行する、単純なアクションとして解釈され、他のオブジェクトに対するメソッドやプロシージャの呼び出しにはなりません。
[<m>]はオプションで、<m>に対しては一文字以上の文字列のニーモニックを指定します。数値であってはいけません。呼び出し先がアクティブな場合には、呼び出し元のオブジェクトを、[<m>]で指定した名前で参照できるようになります。
ノート
(訳注):どのようにすればこの機能が動くのか分かっていません。
<メッセージ>には1行以上のテキストを書くことができます。必要に応じて\nで区切ってください。
'new'という名前のメッセージもしくは、'new('から始まるメッセージは、特別なメッセージとして扱われます。これらのメッセージは、オブジェクト宣言時に'/'を先頭に付加されたオブジェクトの対して、一回だけ送ることができます。'new'メッセージを受信すると、そのオブジェクトはライフライン上に作成されて、見えるようになります。
'destroy'という名前のメッセージもしくは、'destroy('から始まるメッセージも、特別なメッセージとして扱われます。これはアクティブではないオブジェクトにしか送ることはできません。'destroy'メッセージを受け取ると、一時的にアクティブになり、他のオブジェクトに'destroy'メッセージを送ったりすることができます。その最後の活動が終わると、オブジェクトが破棄されます。ライフラインの最後にバツ印が付きます。その状態になると、それ以上メッセージを受け取ることはできなくなります。
アクターはメッセージの送信と、すぐに返ってくる非同期メッセージの受信のみを行うことができます。非同期メッセージは、アクターのメッセージによって開始されたアクティビティが終了したことを通知する場合に使用されます。
もしもアクターが通常のオブジェクトに対してメッセージを送信すると、すべてのアクティビティはその前に終了します。通常、アクターはシーケンス図の最初のメッセージの送信を行いますが、必ずしもそうである必要はありません。アクターが一人もいないシーケンス図もサポートしています。
マルチスレッドのドキュメントを参照してください。
図にアノテーション(注釈)をつける方法は3種類あります。
テキスト記述の中で、'#'から始まる行を書くと、コメントになります。これらの行に何を書いても、図には何も書かれません。ただし、アクティブコメントとして解釈される'#!'を除きます。
以下の形式の行を書くと、図の上側にかかれるテキストとして解釈されます:
#!>>
#!A paragraph
#!of text describing
#!what is going on.
#!<<
2つめの方法として、一連のメッセージを図のフラグメント(1部)として宣言することができます。フラグメントは、これらのメッセージを囲む、枠として表現されます。フラグメントはタイプ(例えば、alt(別案), cond(条件), opt(オプション))を持ちます。これは枠の左上の角に書かれます。また、枠の左上の四角い枠の中に書かれるテキストを記述することもできます:
[c:<タイプ> <テキスト>]
foo:bar.message_1
foo:bar.message_2
...
foo:bar.message_n
[/c]
Fragments can be slightly abused: if you write [c <text>] (without the colon), all of the text will appear in the small box in the top left corner. Fragments may contain sections. To open a new section, insert a line of the form:
フラグメントはこのような用途とはまた別の使い方をすることもできます。コロン(:)をつけないで、[c <text>]と書くと、すべてのテキストが枠の左上の角の小さい箱の中に書かれます。フラグメントはセクションも持つことができます。新しいセクションを開く場合には、以下のような形式の行を挿入します:
--何らかのテキスト
この行を挿入すると現在のフラグメントの左端から右端まで、点線が引かれて、その線の下に'何らかのテキスト'とテキストが表示されます。
3つめのアノテーションはノートです。ノートを記述すると、付箋紙を模したボックスがライフラインの右側に現れます。ノートはメッセージセクションの一部です。ボックスは、ボックスが属するメッセージの矢印の、テキストが表示されているのと同じ位置の上段配置されます。文法としては番号が後ろに付いて、<<のない、ヒアドキュメントとほぼ同じです:
*<番号> <名前>
複数
行の
ノート
*<数値>
<名前>はノートを表示する位置のすぐ左のライフラインの名前です。<番号>はノートを識別する、ユニークな数値を入れます。スクリプトのどこであっても、この数値を使ってノートを参照して、ノートとメッセージ、もしくはライフラインを関連付けすることができます。ノートが宣言される前であっても問題ありません。実際に参照する場合には、以下のようにして、メッセージもしくはライフライン名の前に、関連する数値の参照を追加します:
サンプル:
*5 foo
fooはbarのwaitメソッドをコールします。
*5
*6 foo
fooはbarを待ちます
*6
*7 foo
barの準備が完了しました
*7
(5,7)foo:ready=bar.wait()
(6)foo
bar:何かする
(6)foo
bar:さらに何かする
"*"の代わりに"+"を使用すると、ノートのボックスは必要なだけ垂直な空間を消費します。同じ水平な空間には、メッセージの矢印や、ノートのボックスが来ることがなくなります。"*"を使用すると、ノートのボックスは、もっとも近所のライフラインをつなぐメッセージの矢印に属している場合のみ、縦方向の空間を消費するようになります。
"+"を使用した例:
foo:Foo
bar:Bar
+6 foo
fooはbarを待っている
+6
+7 bar
barの準備が完了
+7
(7)foo:ready=bar.wait()
(6)foo
"*"を使用した例:
foo:Foo
bar:Bar
*6 foo
fooはbarを待っている
*6
+7 bar
barの準備が完了
+7
(7)foo:ready=bar.wait()
(6)foo
ノートとオブジェクトを直接関連付けする方法はありません。もしも、オブジェクトかアクターに対して、何か気になることを記述したい場合には、メッセージが何か定義される前に該当するライフラインにノートを付加することで行うことができます。
"link:"で始まる一行ノートは、他のシーケンス図へのリンクであると解釈されます。その行の残りの部分は他のsdファイルへのURI(RFC 3986参照)になります。もしも相対パスとしてURIが記述された場合には、現在のシーケンス図のファイルを起点としたパスとして解決されます:
#ファイル"a.sd"の開始
a:A
*1 a
link:b.sd
*1 a
#終了
#ファイル"b.sd"の開始
#"a.sd"と同じディレクトリに置かれている
b:B
#終了
ここで、a.sdの図の中のノートをクリックすると、b.sdがオープンされます。
もしも"link:"の後ろの文字がスペースを含んでいると、厄介なことが発生します。これはURIの文法としては間違っているからです。スペースを記述する場合には、"%20"に置換する必要があります。特にWindowsでは"Program files"などのように、スペースを含むディレクトリ名が、例外とは言えないぐらい頻繁に使用されています。絶対パスで指定しようした場合には1度ならず、何度も間違って実行してしまうでしょう。
これらの文字列をURIとして処理する目的は、プラットフォーム間で共通の記述をさせたかったからです。そのため、Windowsのプラットフォーム上であっても、パスとファイルの区切り文字には"/"を使用しなければならないということも示しています。絶対パスを指定したい場合には、書き出しは"file:/"としなければなりません。