Checkstyleを使って適切なコーディング標準を簡単に維持するはじめに一貫して明白で、品質に優れ、保守しやすいコードを記述することは、好条件に恵まれていたとしても、ある程度の訓練を要する技術です。コーディング標準には、コードの記述方法に関する規則と推奨事項が提示され、適切なコーディング習慣も記載されています。最近、コーディング標準は、アジャイル開発の重要なベストプラクティスとして普及してきたため、ソフトウェア開発においてその重要性が見直され、認知度が上がってきました。 Checkstyleは、コーディング標準とベストプラクティスの実践を支援するオープンソースツールです。スタンドアロンツールとして使用すると、総合的なコード品質のレポートを生成できます。また、開発者の作業環境に組み込んで、記述しているコードに関する、リアルタイムのビジュアルなフィードバックを提供することもできます。 コーディング標準コーディング標準は、言うまでもなく、多くの開発環境における重要なベストプラクティスです。この標準には、古くからの伝統と規則に加えて、ソフトウェアの記述方法のベストプラクティスが盛り込まれています。その推奨事項は、コードのレイアウトや、クラスや変数の名前付けの標準的な方法を定義するという単純なものから、コードの信頼性やパフォーマンスを高めるためのものまで、多岐にわたります。 しかしながら、Vrije大学(アムステルダム)のコンピュータサイエンスの教授であり、Minixオペレーティングシステムの作成者であるAndrew S. Tanenbaumは、「標準の良い点は、多くの選択肢が用意されていることである」と述べています。各企業、チーム、個人の開発者は、長い間に、それぞれ異なるプログラミング方法や習慣を確立しています。異なるプログラミングスタイルや規則を使用する開発者が、共通のコードベースで共同作業を行う場合に、問題が生じます。 実際、インデントや命名規則など、多くの標準は、ほとんどが勝手に行われています。Sunのコーディング規則では、中括弧は命令の直後に指定することが推奨されています。
while (i < 10) {
i++;
}
一方、多くのC++開発者は、改行してから中括弧を指定します。
while (i < 10)
{
i++;
}
どちらのスタイルの方が適切であるかを示す、本当に客観的な理由はありません。重要なのは、プロジェクト内で適切に定義され、認められたスタイルを使用することです。コーディング標準が認識されることで、チームや会社が一致して共同作業を行うことができます。チームメンバが、確立された一連のコーディング標準を理解すれば、コードのレイアウトや変数の命名規則などの細部に頭を悩ますことなく、本来のコーディング作業に集中できます。新しいプロジェクトチームの場合は、プロジェクトの開始時に、 標準を一貫して使用することで、チームや会社内の「チームワーク」も高まります。また、一貫性をもって配置され、周知の規則に従っているコードは、理解しやすく、保守も簡単です。 Sunによって、Java言語に関するコーディング規則のセットが定義されており、これは業界で広く受け入れられています。多くの企業やオープンソースプロジェクトも独自のコーディング規則のセットを公開していますが、ほとんどの場合、Sun規則がベースになっています。いくつかの典型的なコーディング標準を、以下に示します。
int classNumber; // The child’s class, from 1 to 8 int age; // The child’s age 以下の宣言は、適切ではありません。
int classNumber, age;
while (i < 10) {
i++;
}
開発チームのすべてのメンバと、会社やプロジェクトで適用する規則について話し合うとよいでしょう。各ルールを明確にして、判断します。ルールの基になる目的は何でしょうか。ルールは組織的に適用されるのでしょうか、それとも例外はあり得るのでしょうか。多くのベストプラクティスと同様、コーディング標準が効果を発揮するためには、チーム全体がこれを適切に理解する必要があります。 CheckstyleについてCheckstyleは、Javaコードに対してコーディング規則とベストプラクティスルールを適用するためのオープンソースツールです。Javaソースコードを分析して、標準違反を報告することにより動作します。プラグインを通じて好きなIDEに統合できるため、開発者は、公式標準の違反を即時に確認し、訂正することができます。また、見つかった違反をまとめたプロジェクト全体のレポートを生成することもできます。 Checkstyleには、コードの形式や命名規則から、EJBベストプラクティスやコードの複雑なメトリクスに至るまで、多様な範囲の問題を扱う120を超えるルールと標準を含んだ、標準的なSun規則が最初から組み込まれています。Checkstyleは、以下のものに関連する標準をサポートします。
Eclipse内でのCheckstyleの使用Checkstyleは、コマンドラインから使用したり、AntまたはMavenビルドスクリプト内で使用したりなど、さまざまな方法で使用できます。しかし、最も効率的なのはIDE内で使用する方法です。この方法だと、誤り部分を即時に訂正でき、手間もほとんどかかりません。Eclipse、IntelliJ、NetBeans、JBuilder、JEditなど、主要なほとんどのJava IDEには、Checkstyle用のプラグインが存在します。以降では、Eclipse内でCheckstyleを使用する方法について説明します。 Eclipse Checkstyleプラグインは、http://eclipse-cs.sourceforge.net/index.htmlにあります。まず、プラグインをインストールする必要があります。これには、プラグインのリモートアップデートサイトを使用するのが最も簡単です(図1を参照)。 プラグインをインストールしたら、特定のプロジェクトに対してCheckstyleチェックを起動できます(図2を参照)。プロジェクトプロパティウィンドウを開き([Project]→[Properties])、Checkstyleプロパティエントリを選択し、[Checkstyle active for this project]チェックボックスをオンにして、[OK]をクリックします。この時点で、Checkstyleはバックグラウンドタスクとして実行され、プロジェクト内のソースコードを監査します。プロジェクトの規模によっては、多少の時間がかかることがあります。 図2 Checkstyleの起動:Checkstyleは、他の多くのIDEと同様、Eclipse IDE用のプラグインを備えている。 ![]() Checkstyleがその監査を終了すると、通常は、標準違反の長いリストが生成され、[Problems]ビューペインに警告としてリストされます。このリスト内の問題をクリックすると、原因のコードセグメントに自動的にジャンプします。 Checkstyleプラグインは、Javaコンパイラと同じように動作します。Checkstyleが有効なプロジェクト内でJavaクラスを編集および保存すると、コードが自動的にチェックされて、違反が強調表示され、その説明が表示されます(図3を参照)。原因のコードが黄色で強調表示され、その上、対応するマーカーが余白に表示されるため、これを見落とすことはないでしょう。 コーディング標準が適用されるプロジェクトでは、開発者は、Checkstyleが正しく設定されたIDEで作業する必要があります。適切に推奨すれば、開発者は、コーディング標準エラーを構文エラーとほとんど同じものと見なすようになり、コードを記述しながら訂正するようになります。やがて、すべてのチームメンバが、プロジェクト標準を徐々に(かつスムーズに)身につけていきます。これは、コーディング標準を実践する上で最も効率的な方法です。 一方、大規模な既存のコードベースでCheckstyleを実行すると、これまでコーディング標準が実践されていなかった場合や異なるコーディング標準が実践されていた場合は特に、大量のエラーが発生するため、混乱が生じる可能性があります。これは、組織にコーディング標準を導入する方法を検討するときの重要な要因です。 次の節では、チームの特定の要件に合わせてCheckstyleコーディング標準をカスタマイズする方法について説明します。 Eclipse内でのコーディング標準のカスタマイズ構成ファイルを通じて最初から提供されるSunコーディング標準は、場合によっては手に余ることがあります。特に、Checkstyleを使用せずに既に多くのコードが記述されている場合、Checkstyleによって、比較的マイナーなルール違反(行の末尾の空白など)が何百個となく報告されてしまいます。この場合、マイナーであまり重要でない大量の標準の中に、重要な標準が埋もれてしまう恐れがあります。その結果、2つのマイナスの副作用が考えられます。
コーディング標準の採用とCheckstyleによる実践を効果的に進めるためには、多くの場合、より柔軟な方法が必要です。これを実現する最も簡単な方法は、会社または単一のプロジェクト用に特別に設計されたコーディング標準のカスタムセットを作成することです。 Eclipseでは、これを比較的簡単に行うことができます(図4を参照)。[Preferences]ウィンドウにアクセスし、Checkstyleの各種設定を選択してみてください。いくつかの組み込みの構成ファイル(Sunコーディング標準と、Eclipseで使用される既定のコードフォーマットに適用される、多少変更されたバージョンのSun標準)が表示されます。 新しいCheckstyle構成ファイルを作成するには、[New]をクリックします。使用できる構成ファイルの種類は次のとおりです。
プロジェクト関連の構成([Project Relative Configuration])は、該当のCheckstyle構成ファイルが、AntやMavenなど、他のツールによるビルドプロセスでも使用されている場合に、特に効果的です。 新しいコーディング標準のセットを作成する場合は、内部構成([Internal Configurations])で開始して、その内容に自分とチームの他のメンバが納得したら、エクスポートして公開するのが最も簡単です。 プラグインを使ってCheckstyle構成ファイルを設定するのは簡単です。新しい構成をクリックするとウィンドウが表示され、そこに、使用可能なCheckstyleモジュールと、この構成ファイルで有効になっているモジュールが表示されます(図5を参照)。構成ファイルにモジュールを追加するには、目的のモジュールをクリックし、各自のニーズに合わせて構成します。各モジュールには、独自の構成パラメータが用意されています。 コーディング標準のイニシアティブについて、開発チームの賛同を得ることが重要です。このためには、チームで標準のリストを作成し、各標準を検討し、プロジェクトの要望と標準に基づいてモジュールを構成するのが適当です。こうすることで、開発者は各ルールの背後にある原動力を理解でき、その採用が促進されます。 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文字を超える行をチェックするには、次に示すように <module name="LineLength"> <property name="max" value="70"/> </module> <module name="LineLength"> <property name="severity" value="ignore"/> <property name="max" value="70"/> </module> 大部分のモジュールは、既定の設定で適切に動作します。JavadocTypeモジュールは、クラスとインターフェイスのJavadocコメントをチェックします。このモジュールを既定値で有効にするには、構成ファイル内でモジュールを宣言します(TreeWalkerモジュール内でネストする必要があります)。
<module name="JavadocType"/>
既定では、 <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 しかし、年は毎年変更する必要があります。このためには、以下に示すように、RegexpHeaderモジュールを使って行内の正規表現を定義します。 <module name="RegexpHeader"> <property name="header" value="^// Copyright (C) dddd My Company$ ^// 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) dddd 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チェックが <!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サイトで結果を公開します。 プロジェクトのCheckstyle構成ファイルをプロジェクトのソース管理下に置き、開発者の作業環境とビルドツールの両方から同じファイルを参照するとよいでしょう。こうすることで、開発者のマシンとビルドプロセスに同じ標準が適用されます。 コーディング標準の導入ソフトウェアプロジェクト管理における他の多くのものと同様、スタッフの適切なスキルは、新しいコーディング標準の実装の成功につながります。 まず、プロジェクトの一番の優先順位を明確にすることが必要です。管理者(プロジェクトマネージャと上級管理者の両方)は、コーディング標準が重要であることを開発者に理解させる必要があります。そうでなければ、コーディング標準は決して実行されません。コード監査を自動的に生成すること(および公開すること)と、これを開発者の日常業務に組み込むことは別物です。ここでは、個々の教育や指導が役立ちます。プロジェクトミーティングで、コードの監査結果を検討する方法もあります。使用する方法にかかわらず、開発者の賛同を得続けることが重要です。 コーディング標準とコードレビュー自動的なソースコードの監査が、コードレビューに代わることは決してないことに注意してください。コードレビューは、適切に使用すれば、ソフトウェアの品質を向上する強力なツールです。コードレビューは本質的に人間による作業であり、効率的であるためには人間の判断に大きく依存します。 しかし、Checkstyleレポートでは、さまざまなコーディング標準を構成する多数の面倒なチェックが自動的に行われるため、コードレビューが簡単化され、高速化されます。これにより、コードレビューアはより高度な問題に集中できるようになりますし、コードの簡潔性と可読性が向上するため時間の節約にもなります。 コーディング標準を適用すると、最初のうちは、開発者が新しい作業方法に慣れるまで少し時間的なロスが出ます。この点については、開発者と管理者の間であらかじめ話し合っておく必要があります。コーディング標準はプロジェクトと会社のマネジメントに大きく貢献すると開発者が感じれば、コーディング標準は、開発作業の一部にすぐに組み込まれます。開発者がコーディング標準を完全に実践するようになれば、最小限の負担で、明らかなメリットを得ることができます。 著者紹介John Ferguson Smart(John Ferguson Smart)
政府機関や企業の国内外の開発チームから成る大規模なJ2EEプロジェクトに数多く携わる。J2EEのアーキテクチャと開発、およびITプロジェクト管理を専門とする。オープンソースのJavaテクノロジの経験も豊富。自らのテクニカルブログを公開中(www.jroller.com/page/wakaleo)。
|