#はじめに
シーケンス図って、Webで画像検索すると様々な書きかたがされていて、何が正しいのだか分からなくなってしまいます。
そこで、今回は、UML仕様書に書いてあるLoopの書きかたを見てみます。
#UML仕様書の記述
シーケンス図のループは、UML仕様書では「複合フラグメント」の項目に書かれています。
UML2.0仕様書2.1対応 オーム社より
##セマンティクス
interactionOperatorのloopは、CombinedFragmentがループを表すことを意味する。loopオペランドは、何度か繰り返される。ガードは、論理式と同様に、最小と最大のループの反復の数を持つことができる。セマンティクスとしては、ループは(ガードのイテレーション式にある)最低「minint」の回数だけ反復した後、論理式がfalse(偽)であればループは終了する。
##記法
'loop['('<minint>[','<maxint>]')']
<minint>
::=負でない整数
<maxint>
::=負でない整数(<minint>以上 | '*'
'*'
は無限の意
<minint>
だけがある場合、<minint> = <maxint> = <integer>
であることを意味する。
loopだけの場合、最大値は無限で最小値は0であることを意味する。
また、セマンティクスに出てきた「ガード」の記法については、UML仕様書では相互作用オペランドの項に「図を参照」と書かれています。その図を見ると、ガード条件はオペランド内に[ ]
で書くことが分かります。
#これらを分かりやすく直すと
つまり書きかたに、いくつかのパターンがあって、それぞれ以下のような意味になる、ということです。
実用的なイメージが湧くように、コード例も付けました。
##loop ( min , max )
loopに入ったら最低でも3回は処理を繰り返し、その後[ x == true ]が偽になったらループから抜ける。
ループは最大の5回繰り返したら終了する。
for( int i = 0 ; i < 5 ; i ++ ){
if( ( i >= 3 ) && (!(x == true)) ){
break;
}
// 処理
}
無理やり1行にすると、こんな感じ。
for( int i = 0 ; (!( ( i >= 3 && i < 5 ) && (!(x == true)) )) || (i < 5) ; i ++ ){
// 処理
}
ごく一般的にプログラミングされるループは、次のような感じかと思うのですが、
for( int i = 0 ; i < 5 ; i ++ ){
if( x == false ){
break;
}
// 処理
}
UMLで正しく描くと
となり、minに 0を書かなくてはなりません。
※ 0 ,
を書かないと下の loop ( min )の意味になってしまいますので注意してください。
##loop ( min , * )
loopに入ったら最低でも3回は処理を繰り返し、その後[ x == true ]が偽になったらループから抜ける。
for( int i = 0 ; ; i ++ ){
if( ( i >= 3 ) && (!(x == true)) ){
break;
}
// 処理
}
または、
for( int i = 0 ; !( i >= 3 && ( !(x == true) ) ) ; i ++ ){
// 処理
}
##loop ( min )
loopに入ったら3回処理を繰り返す。
※UML仕様書に特段の記載を見つけられなかったが、この場合はガード条件[ x == true ]を入れても意味をなさないと考えられる。
for( int i = 0 ; i < 3 ; i ++ ){
// 処理
}
##loop
loopに入ったあと処理を繰り返し、[ x == true ]が偽になったらループから抜ける。
while( x == true ){
// 処理
}
#おわりに
UMLのループって、意外と奥深いですね。
プログラミング言語のループ文でも、minをサポートしてくれればいいのに、と思いました。
ハードウェア周りの制御では、
「最低何回は処理を回して、そのあとは条件で抜けるのが基本だけれど、タイムアウト処理として最大回数回ったら抜ける」
とか、あったら便利そう。
#現場からのつぶやき(2020/4/9 追記)
いやはや、現場では、モデリングツールは通常 EA(Enterprise Artchtect)か、astahが使われています。
しかし、どちらのツールも、UML仕様に完全準拠していないんですよね...( T T ) 。
なので、現場は、混乱しやすいのだと思います。
ですので、こんな風にすれば? と現場に伝えている内容を、以下に記します。
##astahの現状
astahでそのままloopを描くと、こんな感じになります。
loopの右にガード条件が表示されます。
これは、UML仕様と合っていませんね。
##EAの現状
EAでそのままloopを描くと、こんな感じになります。
複合フラグメントの名前の欄に入力した文字が、loopの回数のエリアに表示されて、
ガード条件は、きちんと表示されていますね。
##提案
よくありがちなのが、
astahならば、
loopの右側に、[〇〇の間]とか書いていたり、
EAならば、
名前のところに「〇〇の間」とか日本語で書いていて、
ガード条件には、ほぼ同じことを、式で書いていたり、抜ける条件を書いている人もいます。
ツールを使って開発しているチーム内で、
UML仕様の表記を共通理解して、ツールに合わせた使いかたをするローカルルールにするのが、ベターかと思います。
それを、以下に記します。
##astahでの書きかたローカルルール
astahならば、ガード条件の中に、loop [ (1,2) [xxx == true] ]
##EAでの書きかたローカルルール
EAならば、名前の欄に**「(1,2)」**、ガードの欄に **[xxx == true]**と書く、
のように、
ルール付けしてはどうでしょうか。