LoginSignup
16
18

More than 5 years have passed since last update.

技術的負債を無くす具体的な施策~循環的複雑度を超お手軽に求める~

Last updated at Posted at 2015-07-27

はじめに

巷ではよく技術的負債について以下のような議論がなされます。

  • 技術的負債を残さないためにどうすればよいか
  • 技術的負債が起こす問題はなにか

けれど、結局、技術的負債は往々に残ってしまうものです。

技術的負債を残さないための施策の多くは、
「テストコードを書こう!」
「継続的にCIを回そう!」
「ソースコードの品質チェックを重点的にやろう!」
といったキャンペーンを行うことで解消しよういったものがほとんどで、
それらは開発者やレビュアの能力や時間に限りがあるためだと私は感じます。

そこで、本投稿では、
「技術的負債の対象になるソースを検知する。なおかつ超簡単に。」
という具体的な方法を紹介したいと思います。
ただ、あくまで参考指標という点はご留意願いたいと思います。

具体的な方法

具体的な方法としてmaven-pmd-pluginでソースチェックを行い、その結果(循環的複雑度)をcsv出力してチェックします。

事前準備(MavenとJavaのインストール)

最新版は以下(詳細は割愛)
以下は大体の方が実行環境をもっていると思うのため事前準備はほぼ不要な認識です。

手順①:pom.xmlを作成

以下のファイルpom.xmlの名称で適当なディレクトリに保存
以下をコピペして文字コードはUTF-8で保存して下さい.

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>pmd.example</groupId>
    <artifactId>pmd-example</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <name>maven-pmd-plugin</name>

    <!-- 実行方法(コード解析):mvn pmd:pmd-->
    <!-- 実行方法(重複解析):mvn pmd:cpd-->
    <build>
        <!-- check target directory -->
        <sourceDirectory>checkSrc</sourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-pmd-plugin</artifactId>
                <version>3.5</version>
                <configuration>
                    <!-- default pmd format xml -->
                    <sourceEncoding>${src.encoding}</sourceEncoding>
                    <targetDirectory>${outputDir}</targetDirectory>
                    <format>${pmd.format}</format>
                    <!--
                        Rule Set list
                        http://pmd.sourceforge.net/pmd-4.3.0/rules/index.html
                        Rule Set setting XML
                        http://grepcode.com/file/repo1.maven.org/maven2/net.sourceforge.pmd/pmd/5.0.1/rulesets/java/codesize.xml
                    -->
                    <rulesets>
                        <!-- default Rule Set -->
                        <!-- <ruleset>/rulesets/java/basic.xml</ruleset> -->
                        <!-- <ruleset>/rulesets/java/unusedcode.xml</ruleset> -->
                        <!-- <ruleset>/rulesets/java/imports.xml</ruleset> -->
                        <!-- include rule Set -->
                        <ruleset>/rulesets/java/codesize.xml</ruleset>
                    </rulesets>
                    <excludeRoots>
                        <excludeRoot>**/test/**</excludeRoot>
                        <excludeRoot>**/example/**</excludeRoot>
                    </excludeRoots>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <reporting>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-pmd-plugin</artifactId>
                <version>3.5</version>
            </plugin>
        </plugins>
    </reporting>

    <properties>
        <src.encoding>UTF-8</src.encoding>
        <pmd.format>csv</pmd.format>
        <outputDir>${basedir}/target</outputDir>
    </properties>

</project>

手順②:チェック対象のソースをchecksrcディレクトリ配下にコピー

pom.xmlファイルを保存したディレクトリにcheckSrcというディレクトリを作成して、チェック対象のファイルを保存。
それで以下コマンドをpom.xmlファイルをカレントディレクトリにして実行

手順③:コマンド実行

コマンドプロンプト
mvn pmd:pmd

するとtarget配下に、pmd.csvファイルが作成されます。

結果

pmd.csvは以下のように出力できます。
あとは、これをExcelでソースして分析するなり、DBに取り込んで解析すればヤバイソースを書く人の傾向なども見えてきます。
継続的にチェックするならタスク化してしまえば完了です。

Problem Package File Priority Line Description Rule set Rule
1 jp.co.hogehoge C:\Project\test\pmd\checkSrc\Sample.java 3 18 The class 'Sample' has a Cyclomatic Complexity of 101 (Highest = 100). Code Size CyclomaticComplexity
2 jp.co.hogehoge C:\Project\test\pmd\checkSrc\Sample.java 3 18 The class 'Sample' has a Modified Cyclomatic Complexity of 47 (Highest = 46). Code Size ModifiedCyclomaticComplexity
3 jp.co.hogehoge C:\Project\test\pmd\checkSrc\Sample.java 3 18 The class 'Sample' has a Standard Cyclomatic Complexity of 47 (Highest = 46). Code Size StdCyclomaticComplexity
4 jp.co.hogehoge C:\Project\test\pmd\checkSrc\Sample.java 3 24 Avoid really long methods. Code Size ExcessiveMethodLength
5 jp.co.hogehoge C:\Project\test\pmd\checkSrc\Sample.java 3 24 The method 'checkInput' has a Cyclomatic Complexity of 100. Code Size CyclomaticComplexity

諸々の解説

循環的複雑度(CyclomaticComplexy)とは

端的にいえば、if文やfor文、whileやCASE文など分岐が発生する数+1です。
つまりは、それはテストケースが必要な数であり、
循環的複雑度の値に応じて、そのプログラムのバグ混入率は、下表のようになるとされています。

循環的複雑度 複雑さの状態 バグ混入確率
10以下 非常に良い構造 25%
30以上 構造的なリスクあり 40%
50以上 テスト不可能 70%
75以上 いかなる変更も誤修正を生む 98%

※因みに、注意として、上記のソースコードチェックでは循環的複雑度は10以上のものしか検知されません。
(デフォルト設定で、codesize.xmlを修正すれば変更できます。)

以下はPMDの公式HPの循環的複雑度の算出方法になります
http://pmd.sourceforge.net/pmd-4.3.0/rules/codesize.html#CyclomaticComplexity>

循環的複雑度野求め方(PMDのHPより抜粋)
// Cyclomatic Complexity = 12
public class Foo {
1   public void example()  {
2       if (a == b)  {
3           if (a1 == b1) {
                fiddle();
4           } else if a2 == b2) {
                fiddle();
            }  else {
                fiddle();
            }
5       } else if (c == d) {
6           while (c == d) {
                fiddle();
            }
7        } else if (e == f) {
8           for (int n = 0; n < h; n++) {
                fiddle();
            }
        } else{
            switch (z) {
9               case 1:
                    fiddle();
                    break;
10              case 2:
                    fiddle();
                    break;
11              case 3:
                    fiddle();
                    break;
12              default:
                    fiddle();
                    break;
            }
        }
    }
}

PMDを採用している理由

他のソースチェックツールと違って、以下がお手軽な理由と感じています
例えば、大きな利点は以下です。

  • ビルドが不要
  • セットアップが簡単(Maven pluginなので、mavenがsourceを探してきてくれる)
  • CSV出力できる(xml形式だとparseが面倒だが、それも不要)

コピペソースのチェックもできます

コマンドを以下に変えれば、checkDir配下のソースのうちコピペソースのチェックもできます。

コマンドライン
mvn pmd:cpd

※因みにCPDとは、copy paste detectorのことです。

PMDを用いた循環的複雑度以外のソースチェック

上記例は、循環的複雑度をルールセットにもつCode SizeというPMDのソースチェックを利用しましたが、他にも様々なソースチェックを行うことができます。
pom.xmlのrulesets部分を変更すれば、その他のソースチェックも実行できます。

16
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
18