技術的負債を調査する10のポイント(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

技術的負債を調査する10のポイント(翻訳)

6年前に画期的にシンプルなコード品質測定基準を導入して以来、コードの品質を高め、チームの生産性を向上させるのは「明確かつ実行可能な測定基準」であることがわかってきました。次の段階として、プロジェクトを明確に理解する新しい方法を提供するために、コード品質の測定とトラッキング方法に最近改良を加えました。

Code Climateの2つの柱

私たちの新しい評価システムは、「保守のしやすさ」(「技術的負債」と反対の概念)と「テストカバレッジ」という2つの柱の上に構築されています。テストカバレッジの算出方法はシンプルです。テストでカバーされたコード行数を、カバー可能な総行数と比較してパーセントで表現し、AからFまでのランキングを割り当てています。

一方、技術的負債の測定は困難を伴います。静的解析はコードベースにおける構造に潜む問題を検査しますが、ツールが変わると対象となる問題も変わってしまう(しかも重複が多くなる)傾向があります。測定のための単一の標準というものがこれまで存在しなかったので、私たちはそのための標準の作成に取りかかりました。

技術的負債の調査を標準化する目的は次のとおりです。

  • 言語を問わず適用できること: 優れた標準は、Java/Python/JavaScriptなどのさまざま言語に適用したときにも違和感を生じてはいけません。複数言語を用いるシステムは今や当たり前であり、エンジニアや組織が扱う言語の数は現在も増加傾向が続いています。ほとんどの言語は、順次/選択/反復(sequence/selection/iteration)という素朴な概念に基づいていますが、関数型プログラミングやOOPのようにコードを組み立てる別のパラダイムも普及しています。幸いなことに、ほとんどのプログラミング言語はファイル/関数/条件文などの同じようなプリミティブに還元できます。

  • 理解しやすいこと: 技術的負債を静的解析で調査する最終目的は、エンジニアがよりよい決定を下す力を与えることです。したがって、調査の価値は、エンジニアがそのデータをどれだけ簡単に利用できるかに比例します。凝りに凝ったアルゴリズムはいかにも「高精度」な雰囲気を醸し出しますが、コード品質の改善に大きく寄与するのは「シンプルかつ実行可能な測定基準」であることがここ数年でわかってきました。

  • カスタマイズの余地があること: 当然ながら、コードの組み立てや編成方法の好みはエンジニアやチームによって違います。技術的負債の優れた調査方法は、そうした好みをサポートできるよう、フルスクラッチの設定を必要とせずにアルゴリズムを調整できなくてはいけません。アルゴリズムは変えませんが、閾値は調整可能です。

  • DRYであること: 確かな静的解析をチェックすることで、相関の高い結果を得られます。たとえば、関数の循環的複雑度(cyclomatic complexity)は、条件ロジックのネストに強く影響されます。私たちは、ある違反を見つけるたびに別の違反まで同時に見つける傾向のあるチェックシステムを避けるようにしました。開発者にチェックを促すのに必要な問題は、1つあればよいのです。

  • (相反する部分について)バランスが取れていること: 測定をトラッキングして1つの振る舞いだけを推奨すると、期待に反して修正が過剰になってしまうことがあります(「測定のゲーム化」と呼ばれることもあります)。コピペコードの存在をチェックするだけでは、エンジニアはごく単純な構造の繰り返しすら避けようとするあまり、書きたくもない無駄に複雑なコードを書いてしまうことがあります。相反する測定基準(複雑さチェックなど)の組み合わせに注力することで、DRYとシンプルさを両立できるエレガントな解決方法を生み出す機会を増やせます。

技術的負債調査の10のチェックポイント

以上の目的を念頭に置いて、ファイル(またはコードベース全体)の保守のしやすさを調査するための技術的負債チェックを以下の10項目にまとめました。

  1. 引数の個数: 引数の数が多いメソッドや関数

  2. 複雑な論理値ロジック: 理解しにくくなる可能性のある論理値ロジック

  3. ファイルの大きさ: 1つのファイルで超過しているコード行数

  4. 同一のコードブロック: 文法上同一のコード(書式が異なる可能性も含む)の重複

  5. メソッド数: 関数やメソッドが多数定義されているクラス

  6. メソッドの大きさ: 1つの関数やメソッドで超過しているコード行数

  7. 制御フローのネスト: ifcaseなどのネストが深くなっている制御構造

  8. return: return文の数が多い関数やメソッド

  9. 類似のコードブロック: 同一とまではいかないが同じ構造を共有している(変数名は違う可能性)コードの重複

  10. メソッドの複雑さ: 理解しにくい可能性のある関数やメソッド

チェックの種類

10のチェックポイントは4つの主要なカテゴリに分けられます。それぞれについて見ていきましょう。

サイズ

チェックポイントのうち、「6. メソッドの大きさ」「3. ファイルの大きさ」「1. 引数の個数」「5. メソッド数」の4つは、単にコードベース内における単位のサイズや個数をチェックします。これらは静的解析の中でも最も基本的なチェックポイントであり、コードをパースしてAST(抽象構文木)を生成する必要すらありませんが、ほとんどのプログラマーはコードにおけるこれらの項目のサイズから多くの問題を認識できます。1画面に収まりきらないメソッドのリファクタリングはつらい作業になります。

「1. 引数の個数」チェックは他と少し異なり、「data clump(データの引き回し)」や「primitive obsession(基本データ型に囚われる)」を検出する傾向があります。多くの場合、システムに新しい抽象化を導入して、システム全体に引き回されがちな個別のデータをまとめることでこの問題を解決でき、コードの意味もより明確になります。

制御フロー

「8. return文」や「7. 制御フローのネスト」チェックの目的は、サイズは適切だが追いにくくなっている可能性のあるコード片を見つけることです。コンパイラは制御が複雑になっても何も困りませんが、頭の中で制御フローを評価するはめになったメンテナンス担当者は気の毒です。

複雑さ

「2. 複雑な論理値ロジック」チェックは、見直しの必要な組合せ爆発の原因となる、演算子だらけの条件を検出します。「10. メソッドの複雑さ」チェックにもその要素が少し含まれており、サイズ/制御フロー/機能単位の複雑さの情報を組み合わせて認知複雑度アルゴリズムを適用することで、あるコード単位が人間のエンジニアにとってどのぐらい理解が困難になるかを見積もります。

コピペ検出

最後の「4. 同一のコードブロック」「9. 類似のコードブロック」チェックは、悪質なコピペコードを検出します。コードのコピー元はdiffに現れず、貼り付けた部分しかdiffに現れないので、コードレビュー中に人間がチェックするのは困難です。幸いなことに、この種の問題の分析はコンピュータが得意とする分野です。私たちの採用したコピペ検出アルゴリズムは、構文木の構造同士の類似性を調べ、あるコードブロックをコピペして変数名を変えても見つけ出してくれます。

評価システム

あるコードブロック内における技術的負債の違反(問題)をすべて特定したら、結果を整形してできるだけわかりやすく表示します。

ファイル評価

最初に、エンジニアが問題解決に要する総時間を問題ごとに見積もります。私たちはこれを「改良時間(remediation time)」と呼んでいます。それほど厳密な時間ではありませんが、問題を比較したり集約したりするのに役立ちます。

あるソースコードファイルから総改良時間を得られたら、文字で表されるランキングに割り当てます。改良時間が少ないほど好ましいのでランキングが上がります。あるファイルの総改良時間が増加すると、リファクタリングの意欲が削がれるため、その分ランキングが下がります。

改良時間ランキング一覧

リポジトリの評価

最終的に、プロジェクト全体の技術的負債にランキングを付ける評価システムを構築しました。やってみると、当然ながら歴史の長い巨大なコードベースほど、小規模な比較対象に比べて技術的負債の総量が絶対的に多くなることがわかりました。このようにして、コードの総行数(LOC)を元にコードベースから総実装時間(人月単位)を見積もり、技術的負債の総時間を総実装時間で割って「技術的負債比率」を算出します。これはパーセントで表され、少ないほどよい値です。

技術的負債算出の公式

この技術的負債比率は最終的にA〜Fの評価システムに割り当てられ、プロジェクト同士の技術的負債を簡単に比較できるようになりました。もちろん、プロジェクト開始後の早い段階で警告を発することができます。

コードベースの技術的負債を無料で調査

本記事でご紹介した、コードベースでの10の技術的負債調査をお試しになりたい方は、ぜひCode Climateをお試しください。オープンソースプロジェクトは常に無料であり、非公開プロジェクトについても14日の無料お試し期間がございます。5分もあればコードベースの抱える問題を検出できます。Code ClimateではJavaScript、Ruby、PHP、Python、Javaをサポートしています。

既にCode Climateをご利用いただいているお客様については、あと数週間ほどで「保守のしやすさ」と「テストカバレッジ」が新たに表示されるようになります。どうぞご期待ください。今すぐお使いになりたい方はメールにてお問い合わせいただければ喜んでサポートいたします。

関連記事

Rails: テストのリファクタリングでアプリ設計を改良する(翻訳)

Ruby on RailsによるWEBシステム開発、Android/iPhoneアプリ開発、電子書籍配信のことならお任せください この記事を書いた人と働こう! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好き。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

BigBinary記事より

ActiveSupport探訪シリーズ