ソフトウェアを劣化させる6つの要素?Axivion Suite入門 その2

ソフトウェアを劣化させる6つの要素

前回のQtの静的解析ツール?Axivion Suite入門 その1では、Axivion Suiteの継続的リファクタリングというアプローチと、ソフトウェアの劣化という概念についてご説明しました。

さて、ここで一度立ち止まって、このソフトウェアの劣化という概念についてもう少し深く考えてみましょう。

Axivionの定義では、ソフトウェアの劣化は以下の6つの原因によって発生します。

  • アーキテクチャ違反/隠れ依存性
  • コードクローン
  • メトリクス違反
  • スタイル違反
  • デッドコード
  • 循環依存

本稿では、これらをひとつずつご紹介いたします。

 

アーキテクチャ違反/隠れ依存性

ソフトウェアのプロジェクトでは、リリースぎりぎりの修正や変更(いわゆるquick dirty fix)によって、ソフトウェアアーキテクチャに違反する実装がされることがあります。

(ここでは、上記画像の一番上のボックスから一番下のボックスにかけてつながっている、ギザギザのある矢印)

アーキテクチャ違反とは、基本的にはアーキテクチャ仕様に記載されていないソフトウェアコンポーネント間の依存性がソースコードに存在する状態を意味します。

言い換えると、アーキテクチャ仕様のソフトウェアコンポーネント同士の依存関係が、実際の実装上のソフトウェアコンポーネント同士の依存関係と一致していない状態です。

アーキテクチャ違反は隠れ依存性となってしまうリスクがあります。これは、プロジェクトのメンバーがだれも気付いていないアーキテクチャ違反を意味します。

隠れ依存性はアーキテクチャ違反よりもさらにタチがわるいものです。

大規模なプロジェクトでは特に、ソフトウェアに変更を加える際に、事前に影響箇所の分析のためにソースコードを読むのはとても非効率です。

なので、ソフトウェアコンポーネントの依存関係が定義されているアーキテクチャ仕様を確認して、「ここを変更したらここに影響がある。だからあそこを変更しよう」といった感じで変更計画を立てるのがよいのですが、

実はアーキテクチャ仕様と実装に相違がありましたとなると、アーキテクチャ仕様を信頼して計画した、安全かつ効率的と判断された変更が、実はソースコード上では、危険かつ非効率なものとなってしまう可能性があるです。

また、この「隠れ依存性」のような「不透明性」は、そのほかにも余計な作業を引き起こしてしまう可能性もあります。(例えば、作りこんでしまった不具合の除去や、どこが違うのかはハッキリしないものの、アーキテクチャとコードが異なることが分かっている場合は、その目視によるレビューなど)

この問題は、アーキテクチャ仕様とソースコードを定期的にシンクすることで避けられるものであり、Axivion Suiteのアーキテクチャ違反/隠れ依存性チェックの機能を使えば、それを行うことができます

 

コードクローン

コードクローンとは、ソースコードに存在する同一もしくは似通ったコードを意味します。

コードクローンは、ソースコード内の不必要な複雑度の増加に寄与するもので、大抵は、ソースコードの変更を、すでに実装済みのコードのコピー&ペースト(また、そこに対する微調整)によって行ってしまうことで発生します。

コードクローンには様々な問題が潜んでいます。

単純にアプリケーションのフットプリントが余分に増えてしまうだけではなく、不具合の入ったコードをコピー&ペーストすることによって不具合が拡散したり、あるクローンコードで見つかった不具合の修正やソフトウェアの変更要求をすべてのクローンに適用する際に工数がかかることや、すべてのクローンを把握していなかったためにそれらの変更が漏れてしまうリスクがなどです。

とはいえ、すべてのクローンを根絶やしにすべき、というわけではないのも事実です。クローンが避けられない場面も存在します。

問題はクローンが存在していること自体ではなく、クローンがコードのどこに存在しているのかを把握、管理できていないことなのです。

Axivion Suiteはタイプ1(全く同一のコード)、タイプ2(タイプ1+変数名などのシンボル名の変更)、(タイプ2+行の追加、削除)の、すべてのタイプのクローンを発見することができます。

ソースコードに存在するクローンを発見することで、それらを削除するにせよ、保持するにせよ、プロジェクトを通して適切に管理していくことが可能になります。

 

メトリクス違反

 

ソースコードがバージョンを重ねるにつれ、その不要な複雑性は増えてしまいがちです。

例えば、ある関数の行数がものすごい量になってしまったり、気づいたらif文のネストがとんでもないことになっていたりすることがあると思います。

当然そういったコードは理解が難しく、変更の際にもより注意を払う必要があります。

つまりこれは工数や不具合を作りこむリスクが増加してしまうことを意味しています。

そういった事態に対処するために、メトリクスの計測を行って、適宜その暴発を管理していくことはとても重要になります。

Axivion SuiteはHISメトリクスオブジェクト指向デザインメトリクス、またユーザの定義した独自のメトリクス基準にソースコードが準拠しているかどうかなどの確認も行うことができます。

そうすることで、ソースコードの複雑性が不必要に増えていってしまう事態に対処することができます。

 

スタイル違反

 

ソフトウェア業界には、ソースコードの記述方法に関して様々なガイドラインが規定されています。例えば、MISRA C/C++, AUTOSAR C++, CERT, CWE, C Secure Codingなどがそれにあたります。

ソフトウェアのプロジェクトには多くのエンジニアが携わります。その中で、どうしてもエンジニア間の実力差というものは生じてしまいます。

特に、CやC++などの言語では、実力差がコーディングに表れやすく、また不適切な記述をしてしまった際の不具合の質(メモリリークやクラッシュなど)も重大となってしまうケースが多いです。

そのため、コーディングの際に特定のスタイルに準拠するようにルールを設定することで、その実力差による弊害を最小限に抑え、コーディングが属人的になってしまうことを防ぎつつ、ソフトウェア全体の品質を底上げすることができます。

Axivion Suiteは、バージョン7.5の時点でMISRA C:2012MISRA C++:2008AUTOSAR C++14にも対応し、CERT C, C++CWEC Secure Codingなどのセキュアコーディングの分野のガイドラインもカバーしています。もちろん、ユーザが定義した独自のコーディングガイドラインへの準拠も設定が可能です。

 

デッドコード

デッドコードとは、ソースコードに記述されてはいるものの、実行されないコードを意味します。

これは、元々はコールされていた関数がソースコードの変更時にコールされなくなったりすることで発生します。

デッドコードの問題としては、実行されるべきコードが実行されていないという明らかな不具合のケース以外にも、工数の増加や、デッドコードが何らかの拍子にデッドコードではなくなった時のリスクというものもあります。

ある研究によれば、ソフトウェア開発のライフサイクルにおける工数の割合の中で、ソースコードの理解ソフト変更(40%)、初期開発(20%)とともに40%の割合を占めることがわかっています。つまり、エンジニアは作業の約4割をソースコードを読んで過ごしているのです。

仮にソースコードの中にデッドコード、つまり動かないコードがあるとすれば、そのコードを読む時間は無駄な時間といえるので、デッドコードは工数の無駄にもつながるのです。また、デッドコードに対して単体テストを書いている場合も、その工数は無駄なものになってしまいます。

そして、デッドコードが復活した際のリスクも見逃せません。ずっとデッドコードとして放置され、化石化したコードがある変更によって動作するようになってしまった場合、その動作によって不具合が発生してしまうリスクがあります。

Axivion Suiteはデッドコードを検知することができるため、デッドコードの存在を把握して適切に管理し、それによって引き起こされる問題に対処することができます。

 

循環依存

 

循環依存とは、ソフトウェアコンポーネントの依存関係が循環していることを意味します。

例えば、もっとも単純な循環依存は、関数Aが関数Bをコールしていて、関数Bも関数Aをコールしているような状況です。

循環依存には、3つの問題があります。1つ目は、無限ループを発生させてしまうリスクです。これは、組込みシステム、とくにセーフィティクリティカルなアプリケーションでは特に重大な問題になってしまう可能性があります。循環依存によって意図しない無限ループが発生した場合、システム全体の動作が止まってしまいかねません。

2つ目は、ソースコードの理解度の低下です。関数などが複雑に絡み合っているシステムは理解が難しく、そこに変更を加えるときに不具合を作りこむリスクも高くなります。とくに依存関係が循環している場合「この関数Aを変更したら関数Bに影響があって、その影響が今度は関数Aに影響して....」といったことを考えながら作業をすることはとても困難です。

3つ目は、ソースコードの再利用が困難になる点です。これは、複雑に絡み合った毛糸を解きほぐして、特定の色の1本を使うのが大変なのと同じで、複雑に依存性が絡み合ったソースコードというのは、コンポーネントの再利用の際にその依存関係を理解して丁寧に解きほぐしていく必要があります。結果的にその作業を断念せざるを得なくなり、そのソースコードを開発するのに費やしたコストや工数が無駄になってしまうのです。

Axivion Suiteは関数の依存関係だけではなく、Includeの循環などに関しても循環関係を検知することができます。それにより循環依存の発生を未然に防止することができます。

 

クリーンなコードを目指す

ここまででご紹介した6つの問題は、ソースコードの不要な複雑度を抑えるためには避けるべき問題です。これらそれぞれに対してKPIを設定し、それを達成していくことで、ソースコードの品質を高く保つことができます。

次回のAxivion Suite入門シリーズ第三弾「アーキテクチャ解析とは?Axivion Suite入門その3」では、Axivion Suiteのユニークな機能、アーキテクチャ分析についての記事を書こうと思います。お楽しみに!

おわりに

Axivion SuiteをはじめとするQtの品質保証ツールにご興味のおありの方は、お気軽にお問い合わせください。

概要のご説明から詳細な技術的相談、ツールトライアルのご案内もいたしております。


Blog Topics:

Comments