Lattix/Understandのメトリクスをデータ分析してみた①([Lattix] Sturtevantの構造複雑度)

はじめに

LattixとUnderstandのメトリクスを活用した様々な分析方法を、分析スクリプトとして紹介したいと思います。

今回のテーマは、「Sturtevantの構造複雑度を使用したメトリクス分析」です。

Lattixから出力したメトリクスレポートを、Pythonのスクリプトで読み取り、構造複雑度として加工した上でグラフにプロットして可視化・分析する手法を3回の記事に分けて紹介します。

このテーマでは、LattixのC/C++(Understand)モジュールのメトリクスレポートを使用します。

※Lattixについては、こちらを参照ください。

Sturtevantの複雑度

まず、このブログで取り扱う「Sturtevantの複雑度」という言葉に馴染みのない方も多いでしょう。
Sturtevantの複雑度とは、アーキテクチャ(設計依存間の依存性(結合状態))を計測し、システムの特徴を研究するグループの、Sturtevantという人物が、研究で使用したアーキテクチャ構造に対するメトリクスのことを指しています。

そのメトリクスのひとつが、Visibility Fun-in/out(VFI/VFO)です。Visibility Fun-in/outとは間接的な依存要素数も含めたFun-in/outの数を指します。このメトリクスの値をもとに、
Architectural Complexity(構造複雑度)の分類分けとして、以下のように4つの領域に分類分けを行います。

※Visibility Fun-in/outの詳細に関しては、第2回記事にて説明します。

  • Peripheral複雑度 低
    Peripheralに属するファイルは、周囲に影響を及ぼさず、また、残りの多くのファイルから影響を受けない
  • Utility複雑度 やや低
    システムの大半はこれにUtilityに属するファイルに依存する。しかし、このUtilityに属するファイルはほかのファイルに対して依存が少ない。依存が内包され安定している。
  • Control : 複雑度 やや高い
    Controlに属するファイルは機能性を操作するため、他ファイルへの依存が高い。
  • Core複雑度 高い
    Coreに属するファイルは、他のファイルに対して直接あるいは間接的に共同依存する。また、大きな循環を含むシステムに不可欠な形成する。これらの領域は小さなコンポーネントに分解するのが難しく、また、大きくなりすぎる場合は、管理不能になる可能性がある。


構造複雑度の分類イメージ図

この、4つの分類で[Peripheral]から[Core]のバグ密度を比較すると、バグ密度が最大約3.1倍になる。
また、「McCabeのサイクロマティック複雑度」と組み合わせることで、
[McCade数(Low)×Peripehral]と[McCade数(Very High)×Core]で比較すると、
バグ密度が約8.3倍になるというような検証結果が出ています。

※このような分析例は第3回にて、詳細を説明します。

今回のテーマでは、このVisibility Fun-in/outおよびこの分類手法を「Sturtevantの構造複雑度」と定義し、話を進めていきます。

※「Sturtevant の Architectural Complexity (構造複雑度)」については、以下の論文を参照ください。
 Sturtevant, Daniel Joseph /System design and the cost of architectural complexity
 Description:Thesis (Ph. D.)–Massachusetts Institute of Technology, Engineering Systems Division, 2013.
 [https://dspace.mit.edu/handle/1721.1/79551]

※「Sturtevantの構造複雑度」について、過去にJASPIC(日本SPIコンソーシアム)が開催したソフトウェアプロセス改善カンファレンス 2014で、弊社が発表したセッションについてはこちらを参照ください。


まず、Sturtevantの構造複雑度を扱う上で、把握しておくポイントは主に以下の2点です。

  • 依存関係構造の複雑さが、関数ロジック的複雑さと同程度にソフトウェアの欠陥に影響すること
  • 様々な手法で管理された品質の高いソフトウェアでも、構造複雑度を監視することにより、ソフトウェア欠陥をさらに予防することができること

つまり、構造的な複雑さを見える化し、継続的に管理を行うことでソフトウェア欠陥の予防に役立てることができ、また、ソフトウェア開発をより快適に行えるような環境を作り出すことができるということが報告されています。

今回のテーマでは、このSturtevantの構造複雑度を、より簡単に活用し、構造を可視化していこうという試みです。ぜひ最後まで読んでいただければと思います。

本ブログ記事の方向性

さて、前段が長くなりましたが、今回のテーマの全体像についてお伝えしようと思います。
Sturtevantの構造複雑度のテーマでは、3回のブログ記事に分けて投稿していきます。

第1回:Sturtevantの構造複雑度の紹介・Lattixメトリクスレポートを表でプロット今回の内容
第2回:VFI・VFO(Visibility Fun-in/out)を使った閾値分け
第3回:VFI・VFO(Visibility Fun-in/out)の表へのプロットと分析例

詳細は少し変わる可能性はありますが、このような内容でご紹介していきたいと思います。
今すぐ試したい方向けに、計3回の記事で紹介する最終的な出力の例を以下のhtmlファイルにまとめていますので、ご確認ください。

また、弊社にて、今回ご紹介するPythonスクリプトも、Jupyter NoteBookのipynb形式で提供しておりますので、ご気軽にお問い合わせください。

Pythonスクリプトを使って可視化する準備をする

さて、ここから本題に入っていきます。

第1回では、Pythonを使って構造複雑度を測るメトリクスを可視化していきます。

スクリプトを実行するにはJupyter Notebookが使用できるPythonの開発環境が必要です。

実行する場合には、conda系のパッケージ管理ツール(AnacondaMiniconda)をインストールし、Jupyterを入れるのが簡単です。ここでの詳細なインストール手順等は省略します。

以下、実行環境が準備できていることを前提として、スクリプト内部の説明を行います。

まずは、関連するパッケージをインポートします。
今回データ分析用に使用する主なライブラリは以下になります。

  • numpy:数値計算ライブラリ
  • pandas:数表データ用ライブラリ
  • matplotlib:グラフ描画ライブラリ(グラフ描画の標準的なライブラリ※本テーマでは不使用)
  • seaborn:グラフ描画ライブラリ(データ相関の把握に強み※本テーマでは不使用)
  • plotly:グラフ描画ライブラリ(インタラクティブなグラフ)
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from pandas import Series, DataFrame
from numpy.random import normal
import os
import plotly
import plotly.graph_objects as go
import plotly.express as px
from IPython.display import display
plotly.offline.init_notebook_mode(connected=False)

上記を実行することにより、今回使用するパッケージを一括でインポートしました。
これから、 Lattixから出力できる、Lattixメトリクスレポートの読み込みを行っていきます。

Lattixの依存関係フィルターの設定によって、分析の正確性が上がる可能性があるため、最終的に思った結果が出ない場合には、依存関係フィルターの設定の変更も試してみてください。
※依存関係フィルターによりフィルタリングされている場合、メトリクスも値が変わります。

Lattixメトリクスレポートの出力

Lattixでメトリクスレポートを作成するには、ツールバー[レポート]-[メトリクスレポート]を選択します。

Lattix GUI[レポートタブ]

その後、[メトリクス レポート]ダイアログで、「その他(custom)」以外に、全てにチェックを入れて[OK]ボタンをクリックします。

Lattix GUI [メトリクスレポート設定画面]

レポートが生成された場合、下記のような画面が表示されます。[レポートの保存]から、システムメトリクスレポートを保存してください。また、今回はExcel形式のデータを使用するため、保存フォーマットはxlsx形式を選択してください。

Lattix GUI [システムメトリクスレポート画面]

Jenkinsなどからコマンドラインで、出力したメトリクスレポートでも、本記事の内容を利用することも可能です。
以下は、Lattixコマンドラインでのコマンド例です。

ldcreport “C:¥work¥project.ldz” -system_metrics -architecture_metrics -object_oriented_metrics -report:excel2007 -reportFile:”C:¥work¥metrics.xlsx”

Lattixメトリクスレポートの読み込み

上記により、出力したメトリクスレポートを以下のコードで読み取っていきましょう。

例)メトリクスレポートの出力パス:
C:\work\src\c\httpd-2.0.55\httpd-2_システム メトリクスメトリクス システム.xlsx

dirPath = "C:\work\src\c\httpd-2.0.55"
projectName=""
ltxMetricsFileName ="httpd-2_システム メトリクス_メトリクス_ システム.xlsx"

ltx_org_xlsxFile = pd.ExcelFile(dirPath+'\\'+ltxMetricsFileName)

※結合されたPathのなかに、\aなどの正規表現が混ざる場合、ファイルが見つからないため、エスケープを忘れないようにしてください。

そして読み取ったExcelの各シートをPandasのdataframeオブジェクトに読み込ませます。

sheetName_System="メトリクス システム"
sheetName_Architecture="メトリクス アーキテクチャ"
sheetName_Object="メトリクス オブジェクト指向"
df_ltx_org_System = ltx_org_xlsxFile.parse(sheetName_System,skiprows = 2)
df_ltx_org_Architecture = ltx_org_xlsxFile.parse(sheetName_Architecture,skiprows = 2)
df_ltx_org_Object = ltx_org_xlsxFile.parse(sheetName_Object,skiprows = 2)

そして、シートのデータが正しく読み込めているかを確認していきます。

# アーキテクチャメトリクス
df_ltx_org_Architecture
出力例1
# システムメトリクス
df_ltx_org_System
出力例2

このように、LattixメトリクスレポートをPythonスクリプトで加工しやすい形式にすることができました。

終わりに

今回はここまで。

次回は、VFI・VFOを使いながら、閾値分けをして、構造複雑度をさらに活用していこうと思います。ここまで読んでくださりありがとうございました。また次回も見ていただけると嬉しいです。

タイトルとURLをコピーしました
Close Bitnami banner
Bitnami