プログラムコードとそのメトリック

測定...
定期的に関心が現れたり消えたりするプログラミングのトピックの1つは、ソフトウェアコードメトリックの問題です。 大規模なソフトウェア環境では、さまざまなメトリックのカウントメカニズムが時々現れます。 トピックへの波のような関心はこのように見えます。なぜなら、これまでメトリックは主要なもの、つまりそれらをどうするかを思いついていなかったからです。 つまり、ある種のツールを使用していくつかのメトリックをうまく計算できたとしても、次に何をすべきかはしばしば不明確です。 もちろん、メトリクスは、コード品質管理(大規模で複雑な関数は記述しません)、およびプログラマーの「生産性」(引用符で囲む)、およびプロジェクトの速度の両方です。 この記事は、最も有名なソフトウェアコードメトリックの概要です。

はじめに


この記事では、7つのクラスのメトリックと50を超える代表者の概要を説明しています。

幅広いソフトウェアメトリックが表示されます。 当然、既存のすべての指標を提供することはお勧めできません。結果のさらなる使用が不可能なため、または測定の自動化が不可能なため、またはこれらの指標の専門性が狭いため、それらのほとんどは実際には適用されませんが、かなり使用されている指標があります多くの場合、それらのレビューは以下に示されます。

一般的な場合、メトリックの使用により、プロジェクトおよびエンタープライズマネージャーは、開発済みまたは開発中のプロジェクトの複雑さを調査し、作業量、開発中のプログラムのスタイル、および特定のソリューションを実装するために各開発者が費やした労力を評価できます。 ただし、ソフトウェアを開発する際、プログラマーはプログラムのメジャーを最小化または最大化しようとすると、プログラムの効率を低下させるトリックに頼ることができるため、メトリックはアドバイザリの特性としてのみ機能し、完全にガイドすることはできません。 さらに、たとえば、プログラマーが少数のコード行を書いたり、少数の構造的な変更を加えたりした場合、これは何もしなかったことを意味するのではなく、プログラムの欠陥を見つけるのが非常に困難であることを意味します。 ただし、最後の問題は、複雑さのメトリックを使用して部分的に解決できます。 より複雑なプログラムでは、エラーを見つけるのはより困難です。

1.定量的指標


まず、プログラムのソースコードの量的特性を考慮する必要があります(単純さの観点から)。 最も基本的なメトリックは、コードの行数(SLOC)です。 このメトリックは元々、プロジェクトの人件費を評価するために開発されました。 ただし、同じ機能を複数の行に分割したり、1行で記述したりできるという事実により、1行に複数のコマンドを記述できる言語の出現では、メトリックは実際には適用できなくなりました。 したがって、論理的および物理的なコード行があります。 コードの論理行は、プログラムコマンドの数です。 このバージョンの説明には、使用するプログラミング言語とプログラミングスタイル[ 2 ]に大きく依存するという欠点もあります。

SLOCに加えて、定量的特性には次のものも含まれます。

場合によっては、プログラムのスタイルを評価することの間で追加の区別が行われます(F)。 プログラムをn個の等しいフラグメントに分割し、式F i = SIGN(Ncom。I / N i -0.1)に従って各フラグメントのスコアを計算します。ここで、Ncomm。 iはi番目のフラグメントのコメント数、N ii番目のフラグメントのコード行の総数です。 その後、プログラム全体の総合スコアは次のように決定されます:F = AMOUNT F i 。 [ 2 ]

また、プログラムコードの一部の単位の計算に基づくメトリックのグループには、Halsteadメトリック[ 3 ]が含まれます。 これらのメトリックは、次のメトリックに基づいています。

n1-文字を含む一意のプログラム演算子の数

区切り文字、プロシージャ名、および操作記号(演算子辞書)、

n2は、プログラム(オペランド辞書)の一意のオペランドの数です。

N1-プログラム内の演算子の総数、

N2-プログラム内のオペランドの総数、

n1は、一意の演算子の理論的な数です。

n2は、一意のオペランドの理論的な数です。

導入された表記法を考えると、以下を決定できます。

n = n1 + n2-プログラム辞書、

N = N1 + N2-プログラムの長さ、

n '= n1' + n2 '-プログラムの理論上の辞書、

N '= n1 * log 2 (n1)+ n2 * log 2 (n2)-理論的なプログラムの長さ(スタイル的に正しいプログラムの場合、NからNの偏差は10%を超えません)

V = N * log 2 n-プログラムボリューム、

V '= N' * log 2 n 'は、プログラムの理論上のボリュームです。ここで、n *は、プログラムの理論上の辞書です。

L = V '/ V-理想的なプログラムのプログラミング品質のレベルL = 1

L '=(2 n2)/(n1 * N2)-理論的なパラメーターを考慮せずに実際のプログラムのパラメーターのみに基づくプログラミング品質のレベル、

E C = V /(L ')2-プログラムの理解の複雑さ、

D = 1 / L '-コーディングプログラムの複雑さ、

y '= V / D2-式言語レベル

I = V / D-プログラムの情報コンテンツ。この特性により、プログラム作成の精神的コストを決定できます。

E = N '* log 2 (n / L)-プログラム開発時に必要な知的努力の評価、プログラム作成時に必要な基本決定の数を特徴付ける

Halsteadメトリックスを適用する場合、異なる行数と演算子で同じ機能を記録する機能に関連する欠点は部分的に補償されます。

別のタイプの定量的ソフトウェアメトリックは、Jilbメトリックです。 これらは、条件ステートメントまたはループステートメントによるプログラムの飽和に基づいて、ソフトウェアの複雑さを示しています。 このメトリックは、その単純さにもかかわらず、プログラムの記述と理解の複雑さを非常によく反映しており、条件演算子および循環演算子の最大ネストレベルなどのインジケーターを追加すると、このメトリックの有効性が大幅に向上します。

2.プログラム制御フローの複雑さのメトリック


量的指標ではなく、プログラムの制御グラフの分析に基づく次の大きなクラスのメトリックは、プログラム制御フローの複雑さのメトリックと呼ばれます。

メトリック自体を直接説明する前に、理解を深めるために、プログラムの制御グラフとその作成方法について説明します。

いくつかのプログラムを紹介しましょう。 このプログラムの場合、1つの入力と1つの出力のみを含む有向グラフが構築されますが、グラフの頂点は、連続計算のみがあり、分岐演算子とループ演算子がなく、ブロックからブロックへの遷移と相関するプログラムコードのセクションに関連付けられます。プログラム実行の分岐。 このグラフを構築するための条件は、各頂点が最初の頂点から到達可能であり、最後の頂点が他の頂点から到達可能であることです[4]。

結果のグラフの分析に基づく最も一般的な推定は、プログラムの循環的複雑度 (循環的マッケイブ数)[4]です。 V(G)= e-n + 2pとして定義されます。ここで、eは弧の数、nは頂点の数、pは連結成分の数です。 グラフの接続コンポーネントの数は、グラフを強力に接続されたグラフに変換するために追加する必要があるアークの数と考えることができます。 強く接続されたグラフは、2つの頂点が相互に到達可能なグラフです。 正しいプログラムのグラフ、つまり、エントリポイントと「ハング」エントリポイントと出口ポイントから到達できないセクションがないグラフの場合、通常、プログラムの終わりを示す頂点を閉じてエントリポイントを示す頂点への弧を描くことにより、強力に接続されたグラフが取得されますこのプログラムに。 本質的に、V(G)は、強く接続されたグラフの線形独立輪郭の数を決定します。 したがって、正しく記述されたプログラムではp = 1であるため、循環的複雑度の計算式は次の形式を取ります。

V(G)= e-n + 2。

残念なことに、この推定では、巡回構成と条件付き構成を区別できません。 このアプローチの別の重大な欠点は、同じグラフで表されるプログラムの複雑さがまったく異なる述語を持つ可能性があることです(述語は、少なくとも1つの変数を含む論理式です)。

この欠点を修正するために、G。マイヤーズは新しい技術を開発しました。 推定値として、彼は区間を取ることを提案しました(この推定値は区間とも呼ばれます)[V(G)、V(G)+ h]。ここで、単純な述語のhはゼロで、n局所述語のh = n-1です。 この方法により、複雑さの異なる述語を区別できますが、実際にはほとんど使用されません。

McCabeメソッドのもう1つの変更は、ハンセンメソッドです。 この場合のプログラムの複雑さの尺度は、ペア(循環的な複雑さ、演算子の数)として表されます。 この方法の利点は、構造化ソフトウェアに対する感度です。

Chenのトポロジー測定は、プログラムグラフによって形成された領域間の境界線の数によってプログラムの複雑さを表します。 このアプローチは、制御構造の順次接続のみを許可する構造化プログラムにのみ適用できます。 非構造化プログラムの場合、Chenメジャーは条件付きおよび無条件の遷移に大きく依存します。 この場合、メジャーの上限と下限を指定できます。 一番上はm + 1です。ここで、mは論理演算子が相互にネストされている場合の論理演算子の数です。 一番下は2です。プログラムのコントロールグラフに接続されたコンポーネントが1つしかない場合、ChenメジャーはMcCabeサイクロマティックメジャーと一致します。

プログラムの制御グラフの分析のトピックを続けると、メトリックの別のサブグループ-ハリソン、マジェルメトリックを区別できます。

これらの手段は、ネストのレベルとプログラムの長さを考慮に入れています。

各頂点には、描画する演算子に応じて独自の複雑さが割り当てられます。 この初期の頂点の複雑さは、Halsteadメジャーの使用など、あらゆる方法で計算できます。 各述語頂点について、そこから発する弧の端である頂点によって生成されたサブグラフと、そのような各頂点(サブグラフの下部境界)から到達可能な頂点、および述語頂点からいくつかの下部境界までのパス上にある頂点を選択します。 このサブグラフは、述語頂点の影響範囲と呼ばれます。

述語頂点の複雑さの減少は、その影響範囲に含まれる頂点の初期または減少した複雑さの合計に、述語頂点自体の主要な複雑さを加えたものです。

プログラムの機能的尺度(SCOPE)は、制御グラフのすべての頂点の複雑さの減少の合計です。

機能的関係(SCORT)は、制御グラフ内の頂点の数とその機能の複雑さの比であり、末端のものは頂点の数から除外されます。

SCORTは、同じ循環数を持つグラフに対して異なる値を取ることができます。

Pivovarskyメトリックは、循環的複雑度の尺度の別の修正です。 これにより、シーケンシャル制御構造とネストされた制御構造の間だけでなく、構造化プログラムと非構造化プログラムの間の違いも追跡できます。 N(G)= v *(G)+ SUMMA Piの関係で表されます。ここで、v *(G)はV(G)と同じ方法で計算された修正サイクロマティック複雑度ですが、1つの違いがあります。 n-1演算子としてではなく、1つの論理演算子。

Piは、i番目の述語頂点の入れ子の深さです。 述語頂点の入れ子の深さを計算するために、「影響範囲」の数が使用されます。 ネストの深さは、検討中の頂点の球体に完全に含まれるか、または交差する述語のすべての「影響圏」の数として理解されます。 ネストの深さは、述語自体ではなく、「影響範囲」のネストにより増加します。 Pivovarskyメジャーは、順次プログラムから組み込みプログラムへの移行、および非構造化プログラムへの移行とともに増加します。これは、このグループの他の多くのメジャーに対する大きな利点です。

Woodward measure-制御グラフの円弧の交点の数。 このような状況は、適切に構造化されたプログラムでは発生しないため、このメトリックは主に、構造化されていない言語(アセンブラー、Fortran)で使用されます。 交差点は、コントロールが連続演算子である2つの頂点を離れるときに発生します。

境界値法は、プログラムの制御グラフの分析にも基づいています。 このメソッドを定義するには、いくつかの追加の概念を導入する必要があります。

Gを、単一の初期頂点と最終頂点のみを持つプログラムの制御グラフとします。

このグラフでは、アークの入ってくる頂点の数は頂点の負の次数と呼ばれ、頂点から発せられるアークの数は頂点の正の次数と呼ばれます。 次に、グラフの頂点のセットを2つのグループに分割できます。正の次数<= 1である頂点。 正の次数を持つ頂点> = 2。

最初のグループの頂点は受信頂点と呼ばれ、2番目のグループの頂点は選択頂点と呼ばれます。

グラフGのすべての頂点の難易度の減少が合計され、プログラムの絶対境界複雑度が形成されます。 その後、プログラムの相対的な境界の複雑さが決定されます。

S0 = 1-(v-1)/ Sa、

ここで、S0はプログラムの相対境界複雑度、Saはプログラムの絶対境界複雑度、vはプログラムグラフの頂点の総数です。

制御グラフの可能なパスの数で表されるシュナイドウィンドメトリックがあります。

3.データ管理フローの複雑さのメトリック


次のメトリックのクラスは、データ管理フローの複雑さのメトリックです。

Chepinのメトリック:この方法の本質は、I / Oリストからの変数の使用の性質を分析することにより、単一のソフトウェアモジュールの情報強度を評価することです。

I / Oリストを構成する変数のセット全体は、4つの機能グループに分けられます。

1. P-計算のための入力変数および出力を保証するため、

2. M-プログラム内で変更または作成される変数、

3. C-ソフトウェアモジュールの動作の制御に関係する変数(制御変数)、

4. T-プログラムで使用されていない変数(「スプリアス」)。

各変数は複数の機能を同時に実行できるため、対応する各機能グループでそれを考慮する必要があります。

Chepinのメトリック:

Q = a1 * P + a2 * M + a3 * C + a4 * T、

ここで、a1、a2、a3、a4は重みです。

重みは、各機能グループのプログラムの複雑さに対するさまざまな影響を反映するために使用されます。 メトリックの作成者によると、機能グループCはプログラムの制御フローに影響を与えるため、最大の重み3を持っています。 残りのグループの重みは、a1 = 1、a2 = 2、a4 = 0.5のように配分されます。 グループTの重み係数は0ではありません。これは、「スプリアス」変数によってプログラムデータストリームの複雑さが増すことはありませんが、時には理解が困難になるためです。 重みが与えられた場合:

Q = P + 2M + 3C + 0.5T

Spenのメトリックは、各プログラムセクション内のデータアクセスのローカライズに基づいています。 Spenは、プログラムテキストの最初と最後の表示の間にこの識別子を含むステートメントの数です。 したがって、n回出現する識別子は、n-1に等しいspnを持ちます。 大きなスリープでは、テストとデバッグが複雑になります。

データストリームの複雑さを考慮する別のメトリックは、プログラムの複雑さをグローバル変数の呼び出しに関連付けるメトリックです。

モジュールとグローバル変数のペアは(p、r)で示されます。ここで、pはグローバル変数rにアクセスできるモジュールです。 変数rの実際の呼び出しがプログラムに存在するかどうかに応じて、「モジュール-グローバル変数」という2種類のペアが形成されます。実際と可能です。 rがpでアピールする可能性は、rの存在領域にpが含まれることを示しています。

この特性はAupによって示され、Upモジュールが実際にグローバル変数にアクセスした回数と、Pup番号-アクセスできる回数を示します。

実際の呼び出しの数と可能な数の比率が決定されます

Rup = Aup / Pup。

この式は、任意のグローバル変数を参照する任意のモジュールのおおよその確率を示しています。 明らかに、この確率が高いほど、変数の「不正な」変更の確率が高くなり、プログラムの変更に関連する作業が著しく複雑になる可能性があります。

情報フローの概念に基づいて、Kafurメジャーが作成されました。 この尺度を使用するために、ローカルおよびグローバルフローの概念が導入されています。次の場合、AからBへの情報のローカルフローが存在します。

1.モジュールAはモジュールBを呼び出します(直接ローカルストリーム)

2.モジュールBはモジュールAを呼び出し、AはBで使用される値をBに返します(間接ローカルストリーム)

3.モジュールCはモジュールA、Bを呼び出し、モジュールAの結果をBに渡します。

次に、グローバル情報フローの概念を示します。モジュールAがDに情報を配置し、モジュールBがDからの情報を使用する場合、グローバルデータ構造Dを介したAからBへのグローバル情報フローが存在します。

これらの概念に基づいて、値Iが導入されます-手順の情報の複雑さ:
I =長さ*(fan_in * fan_out)2
ここに:

length-手順のテキストの複雑さ(Halstead、McCabe、LOCなどのメトリックなど、ボリュームメトリックのいずれかで測定)

fan_in-プロシージャ内のローカルスレッドの数と、プロシージャが情報を取得するデータ構造の数

fan_out-プロシージャから発信されるローカルスレッドの数と、プロシージャによって更新されるデータ構造の数

モジュールの情報の複雑さは、その手順の情報の複雑さの合計として定義できます。

次のステップは、データ構造に関してモジュールの情報の複雑さを考慮することです。 データ構造に関するモジュールの複雑さの情報測定:

J = W * R + W * RW + RW * R + RW *(RW-1)

Wは、データ構造のみを更新するプロシージャの数です。

R-データ構造から情報のみを読み取ります。

RW-データ構造内の情報の読み取りと更新。

このグループのもう1つの指標は、オビエド指標です。 その本質は、プログラムが線形のばらばらのセクション-プログラムの制御グラフを形成する演算子の線に分割されることです。

メトリックの作成者は、次の仮定に基づいています。プログラマーは、光線間の定義よりも、光線内の変数の使用の関係を、光線間よりも簡単に見つけることができます。 各レイのオカレンスの数は、各レイのオカレンスを使用する変数の総数よりも重要です。

R(i)が光線iの半径に位置する変数の定義オカレンスのセットを示すようにします(変数の定義オカレンスは、変数がローカルで定義オカレンスを持っている場合、または以前のレイに定義オカレンスがある場合、光線の半径にあります)途中でローカルな定義はありません)。 V(i)により、光線iに既に存在する変数のセットを示します。 次に、i番目の光線の複雑さの尺度は次のように定義されます。

DF(i)= AMOUNT(DEF(v j ))、j = i ... || V(i)||

ここで、DEF(v j )は、集合R(i)からの変数v jのオカレンスの定義数、および|| V(i)|| セットV(i)のカーディナリティーです。

4.制御フローとプログラムデータの複雑さのメトリック


メトリックの4番目のクラスは、定量的メトリックのクラス、プログラムの制御フローの複雑さのメトリックのクラス、および制御データのフローの複雑さのメトリックのクラスの両方に近いメトリックです(厳密には、このメトリックのクラスとプログラムの制御フローの複雑さのメトリックのクラスは同じクラスです-トポロジメトリックですが、より明確にするために、このコンテキストでそれらを分離することは理にかなっています)。 このクラスのメトリックは、定量計算と制御構造の分析の両方に基づいて、プログラム構造の複雑さを確立します。

これらの測定基準の最初は、M-Measure [5]のテストです。 テスト尺度Mは、次の条件を満たす複雑さの尺度です。

メジャーは、ネストの深さとともに増加し、プログラムの長さを考慮します。 通常の投資に基づく測定は、テスト測定と密接に関連しています。 このプログラムの複雑さの尺度の考え方は、プログラムの制御グラフを記述する必要最小限の括弧で正規表現の文字(オペランド、演算子、括弧)の総数を計算することです。 このグループのすべての測定値は、制御構造のネストとプログラムの長さに影響を受けます。 ただし、計算の複雑さのレベルは増加します。

また、ソフトウェアの品質の尺度は、プログラムモジュールの接続性です[6]。 モジュールが密結合している場合、プログラムの変更が難しくなり、理解しにくくなります。 この測定値は数値で表現されていません。 接続されたモジュールの種類:

データ接続-モジュールがパラメーターの転送を通じて相互作用し、各パラメーターが基本情報オブジェクトである場合。 これが最も好ましいタイプの凝集です。

データ構造の接続性-1つのモジュールがデータ交換のために別の複合情報オブジェクト(構造)を送信する場合。

接続の制御-情報オブジェクトを別のオブジェクトに送信する場合-内部ロジックを制御するために設計されたフラグ。

モジュールは、グローバルデータの同じエリアを参照する場合、共通エリアで接続されます。 第一に、グローバルエリアを使用するモジュールでエラーが他のモジュールで予期せずに発生する可能性があるため、共通エリアでの接続(凝集)は望ましくありません。 第二に、プログラマーが特定のモジュールでどのデータが使用されているかを判断するのが難しいため、そのようなプログラムは理解するのが困難です。

コンテンツの結合-モジュールの一方が他方の内部で参照されている場合。 これは、モジュール性の原理、つまり モジュールをブラックボックスとして提示します。

外部接続-2つのモジュールは、通信プロトコルなどの外部データを使用します。

メッセージの助けを借りた接続は、最も自由な接続形式です。モジュールは互いに直接接続されておらず、パラメーターを持たないメッセージを通じて報告されます。

接続性の欠如-モジュールは相互作用しません。

サブクラスの関連性は、親クラスと子孫クラスの関係であり、子孫は親に関連付けられ、親は子孫に関連付けられていません。

時間関連-2つのアクションが1つのモジュールにグループ化されるのは、状況を考慮して、同時に発生するためです。

モジュールの安定性に関する別の尺度はコロフェロ尺度[7]です。これは、安定性がチェックされるモジュール以外のモジュールで行う必要がある変更の数として定義でき、これらの変更はチェックされるモジュールに関係します。

このクラスの次のメトリックは、McClureメトリックです。 このメトリックを計算する3つの段階が区別されます。

1.各制御変数iについて、その複雑度関数C(i)の値は、式C(i)=(D(i)* J(i))/ nによって計算されます。

ここで、D(i)は変数iの範囲を測定する数量です。 J(i)は、変数iを介したモジュールの相互作用の複雑さの尺度です。nは、パーティションスキーム内の個々のモジュールの数です。

2.パーティションスフィアに含まれるすべてのモジュールの複雑度関数M(P)の値は、式M(P)= fp * X(P)+ gp * Y(P)によって決定されます。
ここで、fpおよびgpはそれぞれ、モジュールPの直前および直後のモジュール数です。X(P)はモジュールPにアクセスする複雑さです。

Y(P)-他のモジュールのモジュールPからのコール制御の複雑さ。

3.プログラムをモジュールに分割する階層スキームの総複雑度MPは、次の式で与えられます。

P-プログラムモジュールのすべての可能な値に対して、MP = AMOUNT(M(P))。

このメトリックは、機能仕様と管理構造を定義する階層モジュールで構成される、適切に構造化されたプログラムを対象としています。 また、各モジュールには1つの入口点と1つの出口点があり、モジュールは1つの機能を実行し、モジュールの呼び出しは階層制御システムに従って実行され、プログラムモジュールのセットの呼び出し比率が設定されることも理解されています。

また、情報概念に基づいたメトリック-ベルリンガーメジャー[8]もあります。 複雑さの測度はM = SUMMAf i * log 2 p iとして計算されます。ここで、f iはi番目の文字の出現頻度、piはその出現確率です。

このメトリックの短所は、多数の一意の文字を含むが少数のプログラムが、少数の一意の文字を含むが多数のプログラムと同じ複雑さを持つことです。

5.オブジェクト指向メトリック


オブジェクト指向プログラミング言語の開発に関連して、オブジェクト指向メトリックとも呼ばれる新しいクラスのメトリックが登場しました。 このグループで最も一般的に使用されるのは、MartinメトリックセットとChidamberおよびKemereraメトリックセットです。 最初に、最初のサブグループを検討します。

Martinメトリックの検討を開始する前に、クラスのカテゴリの概念を導入する必要があります[ 9 ]。 実際には、クラスを他のクラスから分離して再利用することはめったにありません。 ほとんどすべてのクラスには、連携して動作するクラスのグループがあり、そこから簡単に分離することはできません。 そのようなクラスを再利用するには、クラスのグループ全体を再利用する必要があります。 このようなクラスのグループは強く結びついており、クラスのカテゴリと呼ばれます。 クラスカテゴリが存在する場合、次の条件が存在します。

クラスカテゴリ内のクラスは、すべて一緒に変更しようとする試みから閉鎖されます。 つまり、1つのクラスを変更する必要がある場合、このカテゴリのすべてのクラスが変更される可能性が高くなります。 クラスのいずれかが何らかの変更に対して開かれている場合、それらはすべてその種類の変更に対して開かれています。

カテゴリ内のクラスは一緒にのみ再利用されます。 これらは相互依存関係にあり、互いに分離することはできません。 したがって、カテゴリ内の1つのクラスを再利用しようとすると、他のすべてのクラスを再利用する必要があります。

カテゴリ内のクラスは、共通の機能を共有するか、共通の目標を達成します。

カテゴリの責任、独立性、および安定性は、このカテゴリと相互作用する依存関係をカウントすることで測定できます。 次の3つのメトリックを定義できます。

1. Ca:求心性グリップ。 このカテゴリ内のクラスに依存するこのカテゴリ外のクラスの数。

2. Ce:遠心クラッチ。 このカテゴリ外のクラスに依存するこのカテゴリ内のクラスの数。

3. I:不安定性:I = Ce /(Ca + Ce)。 このメトリックの値の範囲は[0,1]です。

I = 0は最も安定したカテゴリを示します。

I = 1は最も不安定なカテゴリを示します。

次のように、抽象性を測定するメトリックを定義できます(カテゴリが抽象の場合は、十分に柔軟で簡単に拡張できます)。

A:要約:A = nA / nAll。

nAは、カテゴリ内のabstract_classesの数です。

nAll-total_number_classes_of_category。

このメトリックの値は、範囲[0,1]で異なります。

0 =カテゴリーは完全に特定的であり、

1 =カテゴリは完全に抽象的です。

現在、Martinのメトリックに基づいて、抽象性と不安定性の関係を示すグラフを作成できます。 式I + A = 1で定義された線を作成すると、この線には、抽象性と不安定性のバランスが最も良いカテゴリがあります。 この行はメインシーケンスと呼ばれます。

次に、さらに2つのメトリックを入力できます。

メインシーケンスまでの距離:D = |(A + I-1)/ sqrt(2)|

メインシーケンスへの正規化距離:Dn = | A + I-2 |

ほぼすべてのカテゴリについて、メインシーケンスに近いほど良いことは事実です。

メトリックの次のサブグループは、ChidamberおよびKemererメトリックです[10]。 これらのメトリックは、クラスメソッド、継承ツリーなどの分析に基づいています。

WMC(クラスごとの加重メソッド)、すべてのクラスメソッドの合計複雑度:WMC = SUMMAc i 、i = 1 ... n、ここでc iはi番目のメソッドの複雑度で、メトリック(ハルステッドなど)によって計算されます。対象の基準に応じて)、すべてのメソッドの複雑さが同じ場合、WMC = n。

DIT(Depth of Inheritance tree)-継承ツリーの深さ(祖先クラスから特定のクラスへのクラス階層の最大パス)深さは、プログラムの理解と作成の複雑さを大幅に増加させます。

NOC(子の数)-子孫(即時)の数が多いほど、データの抽象化は高くなります。

CBO(オブジェクトクラス間の結合)-クラス間の結合は、ソースクラスが関連付けられているクラスの数を示します。 このメトリックでは、モジュール接続に関して以前に導入されたすべてのアサーションが真です。つまり、CBOが高いと、データの抽象化が減少し、クラスの再利用が困難になります。

RFC(クラスの応答)-RFC = | RS |、ここでRSはクラスの応答セット、つまり、クラスオブジェクトが受信したデータに応じてクラスメソッドによって呼び出される可能性のあるメソッドのセットです。 つまり、RS =(({M}({R i })、i = 1 ... n、ここでMはクラスのすべての可能なメソッド、R iはクラスIによって呼び出すことができるすべての可能なメソッドです。RFC RFCが大きいほど、テストとデバッグが難しくなります。

LCOM(メソッドの結束の欠如)-メソッドのリンクの欠如。 このパラメーターを決定するために、n個のメソッドM1、M2、...、Mnを持つクラスCを検討します。次に、{I1}、{I2}、...、{In}はこれらのメソッドで使用される変数のセットです。 ここで、共通変数を持たないメソッドのペアのセットであるPを定義します。 Q-共通の変数を持つメソッドの多くのペア。 次に、LCOM = | P |-| Q |。 カップリングの欠如は、クラスを他のいくつかのクラスまたはサブクラスに分割できることを示す信号になる可能性があるため、カップリングを増やしてデータのカプセル化を増やし、クラスとメソッドの複雑さを軽減することをお勧めします。

6.信頼性指標


次のタイプのメトリックは、定量的に近いメトリックですが、プログラムのエラーと欠陥の数に基づいています。 これらの各メトリックの機能を考慮することは意味がありません。単にそれらをリストするだけで十分です。最後のチェック以降に行われた構造変更の数、コードレビュー中に検出されたエラーの数、プログラムのテスト中に検出されたエラーの数、および正しいために必要な必要な構造変更の数プログラム作業。 大規模なプロジェクトの場合、これらの指標は通常1000行のコードに関連して考慮されます。 .

7.


, . . . :

H_M = (M + R1 * M(M1) +… + Rn * M(Mn)/(1 + R1 +… + Rn)

M — , Mi — , Ri — , M(Mi) — .

M(Mi) Ri .

, : , SLOC, . «», «» «».

, , . :

(, , , ) (a, b, c, d).

( , , /, ) (x, y, z, p).

, — .

おわりに


, , . , , , , . , — , , - , .

Source: https://habr.com/ru/post/J106082/


All Articles