【コードで分かるUMLシリーズ】シーケンス図の書きかた（UMLとプログラミング言語のbreakの違い）

#はじめに
よく考えると、UMLが特定のプログラミング言語に依存していないことは、
みんなが承知していることだと思います。

でも、UMLの中に出てくる言葉には、特定のプログラミング言語に出てくる言葉と、
同じ言葉が使われていることもあります。

例えば、`break`です。
複合フラグメントの**これ**です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197297/ebf5b8cc-9bf5-ff0b-e04b-7ffa0e4b0511.png)

break文は、おおよそ、C言語系の言語、Java、PHP、Pythonなどの言語にあるようですが、
UML（というモデリング言語）のbreakは、プログラミング言語のそれらとは意味が異なります。

UMLでモデリングしていると、ついつい、プログラミングのbreakと間違えて使ってしまいますが、今回は、純粋にUMLのbreakの使いかたを紹介します。

※ 今回は、UML上のbreakのことを、便宜的に「複合フラグメントbreak」と表記します。

#UML仕様上のbreakの書きかた
まずは、書きかたを押さえないと、意味を説明できなそうなので、書きかたです。
UML仕様書よりもやや砕いていますが、まずは抽象度高めの説明です。

- 「複合フラグメントbreak」は、「一塊のシーケンス処理（※1）」の中に置く。
- 「複合フラグメントbreak」は、それによって処理を無視する全てのライフラインの上をカバーする。

※1：UML仕様書上は、InteractionFlagment(=相互作用の一片 ...とでも訳せば良いか。）です。複合フラグメントで囲まれたシーケンス図や、複合フラグメント内のオペランド（＝点線で分けられた領域）内のシーケンス図、または、1枚のシーケンス図自体のことです。さらに厳密には、InteractionFlagmentには他にも種類がありますが、それらは「複合フラグメントbreak」を囲えないので、ここでは除外しました。

#UML仕様上のbreakの書きかた（具体化版）
今度は、実際にUMLでモデルを描く人の具象度に直した説明です。

- 「複合フラグメントbreak」は、以下に置くことができる。

　- シーケンス図内（他の複合フラグメント内ではなく、直接に）
　- 他の複合フラグメント内
　- 他の複合フラグメントのオペランド内

- 「複合フラグメントbreak」は、それによって処理を抜ける全てのライフラインの上をカバーするように描く。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/197297/914510d9-81da-3f46-dc70-cbbe2142100e.png)

#UML仕様上のbreakの意味
次に、UML仕様の解説をやや砕くと、次のようになります。

- 「複合フラグメントbreak」のガード条件が真のとき、「複合フラグメントbreak」に入ると、「複合フラグメントbreak」内の処理を実行する。代わりに「複合フラグメントbreak」を直接囲んでいる「一塊のシーケンス処理」内の残りの処理を無視する。

#UML仕様上のbreakの意味（具体化版）+ C#コード例
同様に、実際にUMLでモデルを描く人の具象度に直した説明です。

##シーケンス図内に直接「複合フラグメントbreak」がある場合

 - 「複合フラグメントbreak」のガード条件が真のとき、「複合フラグメントbreak」内の処理を実行し、そのシーケンス図の残りの処理をせずに終了する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197297/131f16f8-cca9-7148-d796-e77a94cfa157.png)


```csharp:breaksample.cs
// シーケンス図が、1つのメソッドの場合の例
public void function(){
    // 複合フラグメントbreak の前に描かれた処理
    if( Guard == true ){
        // 複合フラグメントbreak 内に描かれた処理
        return;
    }
    // 複合フラグメントbreak の後に描かれた処理
    return;
}
```

##他の複合フラグメント(loop以外)内に「複合フラグメントbreak」がある場合

 - 「複合フラグメントbreak」のガード条件が真のとき、「複合フラグメントbreak」内の処理を実行し、「複合フラグメントbreak」を直接囲んでいる他の複合フラグメントの残りの処理をせずに終了する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197297/156f0045-88b8-277b-0221-4f42cf5abd54.png)

※altの場合

```csharp:breaksample.cs
switch( XXX ){
case XX1:
    // 複合フラグメントbreak の前に描かれた処理
    if( Guard == true ){
        // 複合フラグメントbreak 内に描かれた処理
        break;
    }
    // 複合フラグメントbreak の後に描かれた処理
    break;
case XX2:
    // ......
    break;
}
```
※alt以外

```csharp:breaksample.cs
{
    /* 実装例が浮かびません... */
}
```

##他の複合フラグメント(loop)内に「複合フラグメントbreak」がある場合(※2）

 - 「複合フラグメントbreak」のガード条件が真のとき、「複合フラグメントbreak」内の処理を実行し、「複合フラグメントbreak」を直接囲んでいる「複合フラグメントloop」を抜ける。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197297/e5f90939-fcfb-1382-88d6-93ff57d47047.png)

```csharp:breaksample.cs
for( int i = 0 ; i < XXX ; i++ ){
    // 複合フラグメントbreak の前に描かれた処理
    if( Guard == true ){
        // 複合フラグメントbreak 内に描かれた処理
        break;
    }
    // 複合フラグメントbreak の後に描かれた処理
}
```
※2：loopだけ特別に分けたのは、「残りの処理を飛ばす」と「抜ける」の日本語上の分かりやすさのためです。UML仕様では分けて説明していません。

#おわりに
いかがでしたでしょうか？
UMLのbreakは、C言語系のプログラミング言語のbreakよりも、「サブルーチンのreturn ＋ 抜ける前の処理を描ける」に近いイメージだと、私には思えました。

C言語系のプログラマやJavaプログラマが、UMLを読んでコーディングするときは、loop以外の複合フラグメント内に「break」とか書いてあっても、たぶん違和感が出てしまうのではないかと思います。
「複合フラグメントalt」とループを抜ける条件などを工夫すれば、「複合フラグメントbreak」を使わなくとも表現はできます。
その点では、UMLの読み手にbreakの意味を教育しないのならば、ループだけに使うのがベターかも知れません。

ただし、ディスプレイの縦に収まらないほどのシーケンス図を描いている場合は、「複合フラグメントbreak」は便利かも知れません。
UMLモデリングツールで、ディスプレーに収まらない範囲まで「複合フラグメントalt」で囲むのは、メンテナンス工数がかさみます。「複合フラグメントbreak」ならば、ディスプレイの大きさを気にする必要はなさそうです。