コード品質の向上(その1)~ Visual Studio 2012 ソリューションシナリオ

<< ”Visual Studio 2012 ソリューションシナリオ" では、開発現場における様々な課題を Visual Studio 2012 によってどのように解決できるのかを紹介いたします。>>

image

 

開発プロジェクトにおける最大の成果物は “動くソフトウェア” であり、またその “ソースコード” でもあります。

一方で全く同じように “動くソフトウェア” であったとしても、「ユーザーからのフィードバックを受け、継続的に価値を提供し続けていく」という視点で考えた際に、メンテナンスが容易な “ソースコード” と、冗長なコードが多かったり、メソッド名がわかりづらい “ソースコード” では、ソフトウェアのライフサイクルを勘案した時に前者のほうがより価値があるのは明らかです。

今回のソリューションシナリオでは、「コード品質の向上 ~その1~」と題して、ソースコードの品質を向上し、よりメンテナンス性の高いコードを書くための Visual Studio 2012 の支援機能を紹介します。

 

image

開発チームにおいてコードのメンテナス性に関する取り組み姿勢や基準を共有しないままプロジェクトを進めてしまうと、以下のような問題が発生します。

  • チームメンバーそれぞれが勝手な命名規則や、独自のコーディングルールに基づいてコードを書いてしまい、プロジェクト全体としてのまとまりがなくなってしまう。また、そのためにコードの可読性が大幅に落ちてしまう。

 

  • メンバーによって「メンテナンス性」、に対する意識が異なるために、チーム全体としての基準があいまいになってしまう。またプロジェクトが進むにつれ、どうしても「甘い」基準に引きずられてしまう。

 

  • 場当たり的なコーディングにより、コピー&ペースト等で似たようなコードが散在してしまい、問題が発生した際に修正個所が複数個所にまたがってしまう。

 

  • コードに集中するあまり、実行時のパフォーマンスに関して十分に考慮されていないプログラムができてしまう。

 

開発プロジェクトにおいてはアプリケーションのライフサイクルの観点から長期的な視野に立ち、メンテナンス性もソフトウェアの品質の一部であるととらえ、コードの品質を向上させることが重要になります。

 

image

コードのメンテナンス性、品質に関する課題に対し、以下のようなプラクティスを推進することで、コードの品質の向上への取り組みを進めることが可能です。

 

コーディング規則やコーディングのプラクティスを活用しよう

チームで開発を行う場合、それぞれの開発者が自分の基準で命名を行ったり、コードの見た目を変更したりすると、コード全体としての統一性がかけてしまい、保守性が犠牲になってしまいます。コードの共同所有を進め、チーム全員でコードのメンテナンスがスムーズに行えるよう、標準的なコーティング規則を定めておきましょう。

また、過去の経験から得られた知識や守るべきガイドラインをまとめておき、共有することでチーム全体でのコード品質に対する意識やナレッジを高めましょう。

例えば、MSDN において公開されている「C# のコーティング規則」、「安全なコーディングのガイドライン」、「クラス ライブラリ開発のデザイン ガイドライン」等のドキュメントを活用し、コードの品質向上を進めましょう。

 

 

コードの保守容易性を数値で測定しよう

コードの保守容易性に関しては、カーネギーメロン大学の研究をもとに提唱されている「サイクロマティック複雑度」と呼ばれる指標があります。具体的にはコードにおける分岐(if や while、for 等)や switch 文における case での振り分けなどの数に基づき、複雑度が増す形での計算式となります。(サイクロマティック 複雑度の簡単な解説は「CA1502: メソッドの実装を複雑にしすぎないでください」のページを参照ください)。

この指標を利用することで、コードの複雑度を数値として計測することが可能です。

同じようにコードの保守性を図るための指標としては、メソッドあたりの行数や、クラスの継承の深さなども利用可能です。

 

 

冗長なコードはリファクタリングによりシンプルなコードにしよう。

プラクティス2で述べたような、ロジック的に複雑で保守容易性の低いコードをリファクタリングしていくのと同時に、冗長なコードも集約し、コードをできるだけシンプルに保ちましょう。

冗長なコード、とは例えば、開発プロジェクトにおいて、一時的な措置、と思ってコピー&ペーストで作成していたロジックが、結局そのまま残ってしまい、似たようなコードがプロジェクト中に散在する、といった状態です。

これらのコードに対してリファクタリングを行っていきます。具体的には、クラスの継承を利用する、あるいは別メソッドとしての再定義することによりコードの再利用を促進したり、異なる型の処理をおこなうロジックであってもアルゴリズムを共通で利用できる場合にはジェネリックによりロジックの集約を行う、といった方法によって、似たコードを削減し、コードをシンプルに保ちましょう。

 

 

実行時のパフォーマンスの観点からもコードのチェックをしよう

コードの品質は見た目の美しさ、だけではなく実行時のパフォーマンスからも考慮されるべきです。

プロジェクトの初期段階からパフォーマンスばかりを意識したコーディングを行う必要はないですが、中盤以降においてはパフォーマンスの観点からもコードの確認を行い、ユーザーに提供する全体的なエクスペリエンスの向上に努めましょう。

 

 

image

Visual Studio 2012 では開発チームがこれらのプラクティス実践をスムーズに行えるように、様々な支援機能を提供しています。


プラクティス1: コーディング規則やコーディングのプラクティスを活用しよう


Visual Studio 2012 においては、コードの静的分析機能を利用することにより、命名規則や保守容易性、設計(デザイン)上のプラクティス、あるいはセキュリティ上の脆弱性、といった観点でコードの分析を行うことが可能です。

例えば、「デザイン上の警告」のルールでは、.NET Framework のデザインガイドラインに基づきコードを分析します。

その他、「グローバリゼーションの警告」「保守性の警告」「セキュリティの警告」などのルールが用意されています。

また、マネージコードだけでなく、C++ のネイティブコードに対する分析機能が用意されています(提供しているルールは「C/C++ コードの警告」を参照してください)。

Visual Studio 2012 において、このコード分析機能を利用するには、プロジェクトのプロパティにおいて「コード分析」のメニューがあるので、このメニューにおいて分析の際に利用するルールセットを選択し、コード分析の実行を行います。image

マネージコードにおけるコード分析メニュー

 

コード分析機能では、あらかじめ用意されたルールに対して、どのルールを利用するか個別に設定を行うことも可能ですし、いくつかのルールの組み合わせにより構成された「Microsoftマネージ最小規則」や「Microsoftマネージ推奨規則」、あるいは「Microsoftネイティブ最小規則」や「Microsoftネイティブ推奨規則」(またさらに C++/CLR 用の最小規則や推奨規則)、を利用する、といった選択も可能です。

例えば、「C++ および DirectX での Marble Maze (Windows ストア ゲーム) の開発」にて公開されている C++ のサンプルアプリ Marble Maze 対して「Microsoft ネイティブ推奨規則」にてコード分析を行うと、エラーおよび警告は1件も報告されませんが、「Microsoft のすべての規則」にてコード分析を行うと、以下のように18個の警告が報告されます。

image

 

このような静的コード分析機能を利用することで、プラクティスやガイドラインに基づいたコーディングができているかを効率的に測定することが可能になります。

※ マイクロソフトでは、サンプルプログラムの公開前にコード分析を行い推奨されるスタイルでのコーディングとなるようにしています。そのため今回のサンプルも、「推奨規則」でのエラー、警告はない状態で公開されています。

 

 


プラクティス2: コードの保守容易性を数値で測定しよう


Visual Studio 2012 においては、コードの保守容易性を測定するための機能として、「コードメトリックスの計算」機能が用意されています。この機能ではコードを静的に分析し、 メソッド(あるいはクラスや名前空間)ごとに、コードの行数や、クラスの結合度、継承の深さといった数値を計測します。また、サイクロマティック複雑度の計測を行い、それらの数値を勘案しながら、「保守容易性インデックス」という数値を計算します。

image

 

「保守容易性インデックス」は最大値が 100 となる指標であり、メソッドあたりのコードが長すぎたり、サイクロマティック複雑度が大きい(分岐が多い)コードに対しては、保守容易性の観点でペナルティ(マイナス値)を付けて計算する数値となります。

上記画面ショットにおける測定サンプルは 「リバーシ、C# と XAML での Windows ストア ゲームの開発」で公開されている Reversi アプリケーションを利用しており、比較的保守性の高いコードになっていることが数値で理解できます。

 

次に、Visual Studio の新規プロジェクトの作成時に、オンラインから入手できるサンプルである Huo Chess (下記画面ショット。検索キーワードとして “chess” を指定)を使用してプロジェクトを作成してみました。

image

 

 

このコードに対してメトリックス計算を行うと、以下のように、保守容易性インデックスの数値としてはあまりよくない結果となります。

image

これは、それぞれのメソッドのコード行数が長く(例えば、上記画面ショットでポイントしているメソッドは 334行)、また if 文による分岐が多いためにサイクロマティック複雑度が高い数値となっているためです。

 

このようなメソッドの場合、Visual Studio のリファクタリング機能を利用することで、ある程度意味のあるまとまりで別のメソッドとしてロジックを切り出して行くことで保守容易性を改善することが可能です。

 

例えば、実際にいくつかのロジックのまとまりを、メソッドとして切り出したのちに、再度メトリックス計算を行うと、以下のようにコード行数およびサイクロマティック複雑度の数値が改善し、保守容易性としても若干の改善がされたことを確認することができます。

image

 

 

  

本ソリューションシナリオは、「コード品質の向上 ~その2~」に続きます。

 

ソリューションシナリオには、以下のシナリオがあります。

 

受け入れテストのリスクコントロール

チーム開発における単体テストの実践 ~ その1 ~

チーム開発における単体テストの実践 ~ その2 ~

手動テストの品質向上

コード品質の向上 ~ その1 ~

コード品質の向上 ~ その2 ~ 

・リアルタイム プロジェクト マネジメント

Web アプリのテストの自動化

ソフトウェアの保守におけるアーキテクチャの理解

チームの総合力の強化

 

 

 

 

それでは!

岩出