SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

Checkstyleを使って適切なコーディング標準を簡単に維持する

コーディング標準の適用を支援するオープンソースツール

  • X ポスト
  • このエントリーをはてなブックマークに追加

XMLでのCheckstyleコーディング標準のカスタマイズ

 Checkstyle構成ファイルの中身は、ソースコードの検証に使用される一連のモジュールを定義する標準のXMLファイルです。各モジュールは、1つの特定の種類のコーディング標準またはベストプラクティスに対応します。

 モジュールは階層構造です。ルートモジュールは常にCheckerモジュールで、ここに他のモジュールが含まれています。モジュールは、サブモジュールを含むこともできます。有名なTreeWalkerモジュールもこの形式に倣っています。TreeWalkerモジュールはJavaソースファイルを解析し、サブモジュールで解析ツリーの各種要因を検証します。実際、Checkstyleモジュールの大部分はTreeWalkerモジュールのサブモジュールです。単純なCheckstyle構成ファイルの抜粋を以下に示します。

<module name="Checker">
    <module name="TreeWalker">
        <module name="JavadocMethod"/>
        <module name="JavadocVariable"/>
            <property name="scope" value="protected"/>
        </module>
        <module name="AvoidStarImport"/>
    </module>
    <module name="PackageHtml"/>
</module>

 モジュールの動作は、プロパティを使ってカスタマイズできます。各モジュールには一連のプロパティがあり、既定値が設定されています。プロパティをオーバーライドするには、モジュールタグの本文にプロパティタグを追加します。例えば、LineLengthモジュールの場合、最大行長の既定値は80文字です。80文字ではなく、70文字を超える行をチェックするには、次に示すようにmaxプロパティを設定します。

<module name="LineLength">
    <property name="max" value="70"/>
</module>

 severityプロパティは任意のモジュールに適用でき、表示されるメッセージの種類を決定します。例えば、モジュールを無効にするには、severityプロパティをignoreに設定します。

<module name="LineLength">
    <property name="severity" value="ignore"/>
    <property name="max" value="70"/>
</module>

 大部分のモジュールは、既定の設定で適切に動作します。JavadocTypeモジュールは、クラスとインターフェイスのJavadocコメントをチェックします。このモジュールを既定値で有効にするには、構成ファイル内でモジュールを宣言します(TreeWalkerモジュール内でネストする必要があります)。

<module name="JavadocType"/>

 既定では、@authorタグは必要ありません。プロジェクトや会社によっては、これが必須の場合もあります。その場合は、次に示すように、このモジュールに対してauthorFormatプロパティも定義します(この例の場合、NULL以外の文字列が該当します)。

<module name="JavadocType">
    <property name="authorFormat" value="\S"/>
</module>

 命名規則をはじめ、多くのモジュールで正規表現が使用されます。例えば、パッケージ名では小文字の英字と数字のみを使用しなければならないという厳密なパッケージ命名規則を、以下に示します。

<module name="PackageName">
    <property name="format"
        value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
</module>

 多くの会社やプロジェクトでは、標準のファイルヘッダー規則を使用します。Checkstyleには、これを実現するための多くの方法が用意されています。単純なケースでは、ヘッダーテンプレートを作成できます。このテンプレートは、一部の行は固定であり、開発者が変更できる行もあります。会社の標準で、以下に示すように、下部に著作権情報を記載するボックススタイルのコメントが課せられているものとします。

////////////////////////////////////////////////////////////////////
// My Project Title
// A description of this file goes here.
//
// Copyright (C) 2006 My Company
////////////////////////////////////////////////////////////////////

 これを簡単に実現する1つの方法は、上記のテキストから成る「java.header」という名前のヘッダーテンプレートを定義し、どの行を修正するかを指示することです。

<module name="Header">
    <property name="headerFile" value="java.header"/>
    <property name="ignoreLines" value="2, 3, 4"/>
</module>
Suppose that all you need to do is to put a copyright line
 at the top of each file:
// Copyright (C) 2006 MyCompany
// All rights reserved

 しかし、年は毎年変更する必要があります。このためには、以下に示すように、RegexpHeaderモジュールを使って行内の正規表現を定義します。

<module name="RegexpHeader">
  <property
    name="header"
    value="^// Copyright \(C\) \d\d\d\d My Company$\n^// All rights reserved$"/>
</module>

 より複雑な正規表現を使用するために、ヘッダーを外部ファイルで定義することもできます。例えば、会社またはプロジェクトの標準で、ソース構成システムに基づく次のような動的要素を含むファイルヘッダーが必要であると仮定します。

////////////////////////////////////////////////////////////////////
// My Project Title
// File: $Id$
// A short description goes here
//
// Last modified $Date$ by $Author $
// Copyright (C) 2006 My Company
////////////////////////////////////////////////////////////////////

 これは、RegexpHeaderモジュールおよび外部ファイルテンプレート(この例の場合はjava.header)を使って設定できます。

<module name="RegexpHeader">
    <property name="headerFile" value="java.header"/>
</module>

 この場合の「java.header」ファイルは、次のように指定されています。

^////////////////////////////////////////////////////////////////////
^// My Project Title
^// File: \$Id.*\$$
^//.*$
^//
^// Last modified \$Date.*\$ by \$Author.*\$$
^// Copyright \(C\) \d\d\d\d My Company
^////////////////////////////////////////////////////////////////////

 この他にも、多くのモジュールを有効化し、構成できます。詳細については、Checkstyleのドキュメントを参照してください。

Checkstyleテストの抑制

 場合によっては、正当な理由から、特定のコードセクションでコーディング標準に違反することがあります。例えば、次のコードは、各百分位の生徒のリストを抽出します。

for (int i = 1; i < 100; i++) {
    List<Student> students
                        = extractCentile(i, examResults);
    ...
}

 このコンテキストでは、例えば値100の使用は明白であり、これをONE_HUNDREDという定数に置き換えてもほとんど意味はありません。Checkstyleでは、さまざまな方法でこの問題に対処できます。こうした特殊ケースに対処する最も簡単な方法は、SupressionCommentFilterモジュールを使用することです。このモジュールによって、あるセクションのコードに対するCheckstyleが無効になります。

// CHECKSTYLE:OFF - 100 is not a "magic number" in this case
for (int i = 1; i < 100; i++) {
// CHECKSTYLE:ON
    List<Student> students
                        = extractCentile(i, examResults);
    ...
}

 XML構成ファイルに関連するSuppressionFilterを使用する方法もあります。この方法の場合、より詳細な抑制を指定できます。この方法は、大きなコードブロックや、複数のクラスにわたってルールを無効にするときに便利です。

<module name="SuppressionFilter">
    <property name="file" value="docs/suppressions.xml"/>
</module>

 上記のコードは、「suppressions.xml」を呼び出しています。これは、特定のクラス、または特定クラス内の特定行に対する特定のチェックを無効にするために作成する必要があるファイルです。次の例では、すべてのJavadocチェックがCatalogクラスの先頭の50行で無効になり、MagicNumberCheckがすべての単体テストクラスで無効になります。

<!DOCTYPE suppressions PUBLIC
    "-//Puppy Crawl//DTD Suppressions 1.0//EN"
    "http://www.puppycrawl.com/dtds/suppressions_1_0.dtd">

<suppressions>
    <suppress checks="Javadoc*"
              files="Catalog.java"
              lines="1-50"/>
    <MagicNumberCheck(suppress checks="
              files="*Test.java"/>
</suppressions>

 この方法の場合、「suppression.xml」ファイルを最新の状態に維持するために、余分な保守作業が必要です。また、開発者はワイルドカードを使いたがりますが、これは、CheckStyle監査の効率を低下させてしまいます。実際、この方法はあまり使用すべきではなく、他の方法を考慮し、他に方法がない場合に限って使用してください。

ビルドプロセスへのCheckstyleの統合

 コーディング標準を定義し、同意したら、これを日常の業務に統合する必要があります。各開発者のマシンのIDEにCheckstyleプラグインを統合するのもよいでしょう。ただし、コーディング標準は、実際にはプロジェクト全体で組織的に実行され、検証されることが必要です。毎晩のプロジェクトビルドがこれに適しています。

 CheckstyleはAntタスクと共に配布され、HTMLフォームのレポートを生成できます。Mavenは、Maven Checkstyleプラグインを通じて、Checkstyleレポートをそのまま統合します(図6を参照)。どのようなビルドツールを使用する場合でも、Checkstyle監査はプロジェクト全体で少なくとも1日に1回は実行して、プロジェクトのWebサイトで結果を公開します。

図6 レポート:Mavenによって生成されたCheckstyleレポート。
図6 レポート:Mavenによって生成されたCheckstyleレポート。

 プロジェクトのCheckstyle構成ファイルをプロジェクトのソース管理下に置き、開発者の作業環境とビルドツールの両方から同じファイルを参照するとよいでしょう。こうすることで、開発者のマシンとビルドプロセスに同じ標準が適用されます。

コーディング標準の導入

 ソフトウェアプロジェクト管理における他の多くのものと同様、スタッフの適切なスキルは、新しいコーディング標準の実装の成功につながります。

 まず、プロジェクトの一番の優先順位を明確にすることが必要です。管理者(プロジェクトマネージャと上級管理者の両方)は、コーディング標準が重要であることを開発者に理解させる必要があります。そうでなければ、コーディング標準は決して実行されません。コード監査を自動的に生成すること(および公開すること)と、これを開発者の日常業務に組み込むことは別物です。ここでは、個々の教育や指導が役立ちます。プロジェクトミーティングで、コードの監査結果を検討する方法もあります。使用する方法にかかわらず、開発者の賛同を得続けることが重要です。

コーディング標準とコードレビュー

 自動的なソースコードの監査が、コードレビューに代わることは決してないことに注意してください。コードレビューは、適切に使用すれば、ソフトウェアの品質を向上する強力なツールです。コードレビューは本質的に人間による作業であり、効率的であるためには人間の判断に大きく依存します。

 しかし、Checkstyleレポートでは、さまざまなコーディング標準を構成する多数の面倒なチェックが自動的に行われるため、コードレビューが簡単化され、高速化されます。これにより、コードレビューアはより高度な問題に集中できるようになりますし、コードの簡潔性と可読性が向上するため時間の節約にもなります。

 コーディング標準を適用すると、最初のうちは、開発者が新しい作業方法に慣れるまで少し時間的なロスが出ます。この点については、開発者と管理者の間であらかじめ話し合っておく必要があります。コーディング標準はプロジェクトと会社のマネジメントに大きく貢献すると開発者が感じれば、コーディング標準は、開発作業の一部にすぐに組み込まれます。開発者がコーディング標準を完全に実践するようになれば、最小限の負担で、明らかなメリットを得ることができます。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

John Ferguson Smart(John Ferguson Smart)

政府機関や企業の国内外の開発チームから成る大規模なJ2EEプロジェクトに数多く携わる。J2EEのアーキテクチャと開発、およびITプロジェクト管理を専門とする。オープンソースのJavaテクノロジの経験も豊富。自らのテクニカルブログを公開中(www.jroller.com/page/wakaleo)。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/385 2006/08/22 15:47

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング