以前、「本質的複雑度の評価」についてご紹介しました。
今回は、本質的複雑度の縮退アルゴリズム(折り畳みの仕組み)について、サンプルコードを用いて紹介したいと思います。
構造の例は、前回と同じです。
この構造では、do-whileや、if文が含まれています。
同じような①と②のif文構造に対して、②は折り畳めますが、①は折り畳むことができません。
違いがあるのはなぜでしょうか。
本質的複雑度の縮退アルゴリズム(折り畳みの仕組み)は、単純な条件構造を、単一のノード(単一の空のステートメント)として置き換えます。
この単純な条件構造とは、条件構造(if-else, case, while, do-while など)の途中から外にジャンプする、あるいは、条件構造の途中に外からジャンプしてくる、といった流れがない条件構造のことを指します。
※上記の構造では、②の部分に該当します。
しかし、例えば、条件文中からの goto や return, break を持つようなパターンは縮退できません。また、条件構造の内部に縮退できないパターンを含む場合も、それ以上は縮退することができません。
※上記の構造では、①の部分に該当します。
今回の構造を、ソースコードで示した例は、以下のとおりです。
void func() { if (1) { do { doSomething(); } while (1); } else { if (1) { // ① if (1) { if (1) { // ② doSomething(); } else { doSomething(); } } else { goto LABEL; } } else { LABEL: doSomething(); } } }
②は単純な条件構造のため、折り畳めますが、①は条件構造の内部に縮退できない goto 文を含むため、折り畳みできずに残ります。
構造図では、赤矢印で示したエッジの部分に該当します。
void func() { if (1) { } else { if (1) { // ① if (1) { } else { goto LABEL; } } else { LABEL: doSomething(); } } }
以上により、今回の構造図では、本質的複雑度(Essential)は4、複雑度(Cyclomatic)は6となります。
Understandは、EssentialやCyclomaticなど、さまざまなメトリクスを取得できますので、品質の計測に是非ご活用ください。