メトリクス計測

SourceMonitorDelphiに対応していたので使ってみました。

計測対象は今回バージョンアップした「簡単点画」、処理が他のものと比べて複雑な「ひとりWiki」、作りがいまいちだと自覚のある「買本」です。

共通ライブラリとしてプロジェクトのフォルダの外にあるソースは対象外。買本はさらにXML Schemaから自動生成したファイルは対象外です。

簡単点画 ひとりWiki 買本
Files 3 25 27
Lines 1,045 8,289 7,982
Statements 544 4,511 4,869
%Comments 11.4 4.5 6.7
Global SR's 0 1 9
Global Var's 0 19 1
Local SR's 0 0 0
Classes 3 27 33
Methods/Class 19.67 11.93 8.15
Var's/Class 39 17.33 12.76
Avg Stmts/Method 5.7 10.7 13.9
Most Complex Method 12 35 72
Avg Stmts/SR 0 11 22.1
Most Complex Subroutine 0 1 56
% Branches 10.3 17.1 17.4
Max Depth 5 7 9+
Avg Depth 1.37 1.9 1.89
Avg Complexity 2.02 3.4 4.12

LinesとStatementsがいわゆるプログラム規模になりますけど、仕事で出てくるような何十万行、何百万行というのと比べるとどれも大したことないですね。

%Commentsがコメントの割合ですけど低いですね。自分で書いて自分でメンテナンスしているので、読めば分かるということもあってあまりコメントは書いていないです。

簡単点画のVar's/Classの数字が大きいのは、全体の規模が小さいためにフォームの部品の影響が大きくなっているせいですね。これは仕方がないかと。

Avgで始まる平均の指標はどれも悪くないように見えます。比較対象が自分のプログラムしかないので感覚ですけど。

Most Complex MethodがひとりWikiで35、買本で72と高め。ひとりWikiの方はWiki記法で書かれた文字列を解析する所で、これを複雑度が小さくなるように書き直すのは難しそうな気がします。複雑度を小さくするだけを目指すなら簡単ですけど、下手に直すと却って読みにくくなりそう。買本の方は以下のプログラムで、いかにも駄目っぽさが漂っています。

class function TSearchParam.IntToRequestMethod(ProductType: TProductType;
  index: integer): TRequestMethod;
begin
  result := rmAsin;

  case ProductType of
    ptBook: begin
      case index of
        0: result := rmKeyword;
        1: result := rmAuthor;
        2: result := rmAsin;
      end;
    end;
    ptMusic: begin
      case index of
        0: result := rmKeyword;
        1: result := rmArtist;
        2: result := rmAsin;
      end;
    end;
    ptDvd: begin
      case index of
        0: result := rmKeyword;
        1: result := rmDirector;
        2: result := rmAsin;
      end;
    end;
    ptElectronics: begin
      case index of
        0: result := rmKeyword;
        1: result := rmAsin;
      end;
    end;
    ptSoftware: begin
      case index of
        0: result := rmKeyword;
        1: result := rmManufacturer;
        2: result := rmAsin;
      end;
    end;
    ptGame: begin
      case index of
        0: result := rmKeyword;
        1: result := rmManufacturer;
        2: result := rmAsin;
      end;
    end;
    ptKitchen: begin
      case index of
        0: result := rmKeyword;
        1: result := rmManufacturer;
        2: result := rmAsin;
      end;
    end;
    ptToy: begin
      case index of
        0: result := rmKeyword;
        1: result := rmManufacturer;
        2: result := rmAsin;
      end;
    end;
    ptBookUs: begin
      case index of
        0: result := rmKeyword;
        1: result := rmAuthor;
        2: result := rmAsin;
      end;
    end;
    ptSport: begin
      case index of
        0: result := rmKeyword;
        1: result := rmAsin;
      end;
    end;
    ptHealth: begin
      case index of
        0: result := rmKeyword;
        1: result := rmAsin;
      end;
    end;
    ptWatch: begin
      case index of
        0: result := rmKeyword;
        1: result := rmAsin;
      end;
    end;
    ptBaby: begin
      case index of
        0: result := rmKeyword;
        1: result := rmAsin;
      end;
    end;
    ptApparel: begin
      case index of
        0: result := rmKeyword;
        1: result := rmManufacturer;
        2: result := rmAsin;
      end;
    end;
    ptBeauty: begin
      case index of
        0: result := rmKeyword;
        1: result := rmManufacturer;
        2: result := rmAsin;
      end;
    end;
  end;
end;