2025年4月19日
今週の活動¶
- Qualitas Corpusのeディストリビューションをダウンロード・インストールした
- それぞれの静的解析ツールにおけるルールの概要
- Checkstyle
- Annotation: アノテーション(@から始まる部分)を検証
- 例:AnnotationLocation: アノテーションの配置場所をチェック
- Block: ブロック(中括弧{}で囲まれた部分)を検証
- 例: AvoidNestedBlocks: 不要なブロックがないかチェック
- Class Design: クラス設計を検証
- 例: DesignForExtension: サブクラスが継承のために適切に設計されているかチェック
- Coding: コードの実装を検証
- 例: ArrayTrailingComma: 配列を初期化する際に末尾のカンマがあるかどうかチェック
- Headers: ソースファイルの先頭部分(ヘッダー)を検証
- 例: Header: ヘッダーが特定の固定文字列に一致するかどうかチェック
- Inports: import文を検証
- 例: AvoidStarImport:
*
記法を使用したimport文がないかチェック
- 例: AvoidStarImport:
- Javadoc Comments: Javadocのコメントを検証
- 例: AtclauseOrder: ブロックタグ(@から始まるタグ)の順序をチェック
- Metrics: コードの複雑さなどの構造的な指標(メトリクス)を測定
- 例: BooleanExpressionComplexity: 式に含まれる論理演算子の数をチェック
- Miscellaneous: 他のカテゴリーに分類されない様々な種類のルールを検証
- 例: ArrayTypeStyle: 配列の型定義の書き方をチェック
- Modifiers: 修飾子を検証
- 例: ClassMemberImpliedModifier: クラスとレコード内の、ネストされた型における修飾子の暗黙的な使用をチェック
- Naming Conventions: 命名規則を検証
- 例: AbbreviationAsWordInName: 識別子名に含まれる略語(連続した大文字の長さ)をチェック
- Regexp: 正規表現を検証
- 例: Regexp: 特定の正規表現の数をチェック
- Size Violations: ソースコードのサイズに関する様々な指標を測定
- 例: AnonInnerLength: 内部の長い匿名内部クラスをチェック
- Whitespace: ソースコード内の空白文字を検証
- 例: EmptyForInitializerPad: for文の初期化部分が空のときに、左括弧の直後に空白があるかどうかをチェック
- Filters: チェックによって生成された警告(audit events)をフィルタリングするための仕組み
- 例: SeverityMatchFilter: 監査イベントの重大度に応じてイベントをフィルタリング
- File Filters: チェックが実行される前にファイルをフィルタリングするための仕組み
- 例: BeforeExecutionExclusionFileFilter: どのファイルをチェック対象から除外するかを決める
- Annotation: アノテーション(@から始まる部分)を検証
- SonarQube
- Standard experience mode: ルールをCode small、Bug、Vulnerability、Security hotspotの4種類に分類
- コードの臭いとバグのルールに基づいて検出した問題は、偽陽性がゼロになることが期待されている
- 脆弱性のルールに基づいて検出した問題の80%以上は、真陽性になることが期待されている
- セキュリティホットスポットのルールに基づいて検出した問題の80%以上は、開発者がレビューした後に、「レビュー済み」として迅速に解決されることが期待されている
- Multi-Quality Rule(MQR)mode: ルールをソフトウェア品質(セキュリティ、信頼性、保守性)ごとに分類
- 保守性と信頼性のルールに基づいて検出した問題は、偽陽性がゼロになることが期待されている
- 脆弱性のルールに基づいて検出した問題の80%以上は、真陽性になることが期待されている
- Standard experience mode: ルールをCode small、Bug、Vulnerability、Security hotspotの4種類に分類
- Checkstyle
- 静的解析ツールは狭義には2種類あると考えられる
- Checkstyleのように、構文やコーディングスタイルなどのシンタックスの一貫性をチェックするもの
- SonarQubeのように、シンタックスとセマンティクスを分析し、構文の問題だけでなく、潜在的なバグやセキュリティの脆弱性も検出するもの
- Qualitas Corpusについての論文を読んだ
- 要約
- 目的
- コードの大規模な実証研究のコストを削減し、同じ成果物に対する測定結果の比較を可能にする
- 背景
- ソフトウェアメトリクスと品質特性との関係が不明確であり、実用的な測定手法の開発が必要
- 内容
- 複数のドメインにわたるJavaシステムのソースコードとバイナリコードの両方を含む
- 選定基準
- Javaで記述、ソースとバイナリの両方が配布、jar形式、誰でも利用可能、ソースとバイナリの関連性が識別可能
- 構造
- システムのコレクションとそれぞれのバージョン、圧縮された配布物と展開形式(binとsrc)、メタデータを含む
- 目的
- 要約
- リファクタリング 既存のコードを安全に改善するを読み始めた
- 開発プロセスにおけるリファクタリングの役割を理解するため
- 時間とともに複雑化するコードの問題に対し、外部的な振る舞いを変えず内部構造を改善する方法を学ぶため
- 研究の動機をユーザーストーリーに沿って整理する
- 例えば、ある企業の開発者は、市場での優位性を保つために、リリースサイクルの迅速さとプロダクト品質の高さを両立させたいと考えている
- そのため、コードベースの保守性を向上させるリファクタリングを定期的に実施している
- しかし、現状の静的解析プロセスではコードの特定時点でのスナップショットしか分析できないため、時間の経過とともに徐々に発生する保守性低下要因を検出できない
- その結果、品質問題が大きくなってから初めて気づくことが多く、修正に多大な時間を要し、計画していたリリーススケジュールを延期せざるを得ない状況に直面することがある
- ここで、現状の静的解析プロセスをリファクタリングの定義に沿って考える
- リファクタリングとは、ソフトウェアの外部の振る舞いを保ったままで、内部の構造を改善していく作業である
- これを踏まえると、現状の静的解析は一時点のコードスナップショットを分析するため、リファクタリングの本質である継続的な改善プロセスを捉えきれないことが分かる
得られた成果¶
- 既存の静的解析ツールでは何を実現でき、何を実現できないのか?
- Checkstyle
- 実現できること
- 統一的なコーディングスタイルの維持
- 構文エラーの検出
- 実現できないこと
- ロジックエラーの発見
- 時間経過による保守性低下の要因特定
- 実現できること
- SonarQube
- 実現できること
- バグやセキュリティの脆弱性を含むコード品質の包括的な分析
- 特定の品質指標の傾向表示
- 実現できないこと
- コード変更の文脈を考慮した分析
- 時間経過による保守性低下の要因特定
- 実現できること
- 「特定の品質指標の傾向表示」と「時間経過による保守性低下の要因特定」の違い
- 特定の品質指標の傾向表示は「何が起きたか」を示すのに対し、時間経過による保守性低下の要因特定は「なぜそれが起きたのか」と「それがどのような結果をもたらすのか」を理解することを目指す
- SonarQubeのような静的解析ツールはコードの状態の変化を数値的に示すことができるが、保守性低下の要因を特定するためには、変更ごとのよりミクロ的な分析が必要になるため、現状の静的解析によるリファクタリングアプローチではリファクタリングのために得られる情報が少ない
- Checkstyle
直面した課題¶
- リファクタリングを中心に議論していくことになるため、ソースコードを用いた例があると説明しやすい
- リポジトリマイニングを行う際のドメインの選定基準について
- Qualitas Corpusについての論文中では、以下のドメインからシステムを選んだと述べられている
- 3D/グラフィックス/メディア
- IDE
- SDK
- データベース
- 図表/視覚化
- ゲーム
- ミドルウェア
- パーサー/ジェネレーター/make
- プログラミング言語
- テスト
- ツール
- これらのドメインをソフトウェアアーキテクチャの観点から分類すると以下のように整理できるのではないか?
- 3D/グラフィックス/メディア
- パイプラインアーキテクチャ、レイヤードアーキテクチャ
- データの流れと変換が重視される
- ゲーム
- エンティティコンポーネントシステム(ECS)、イベント駆動型アーキテクチャ
- リアルタイム処理が必要
- 図表/視覚化
- MVC、MVVM
- データとその表現の分離が特徴
- IDE
- プラグインアーキテクチャ
- 拡張性と柔軟性を重視
- ツール
- Commandパターン、パイプ&フィルターパターン
- 単一責任の原則に基づいた設計が一般的
- テスト
- 制御の反転(Inversion of Control、IoC)
- 拡張性と再利用性を重視
- SDK
- API駆動型アーキテクチャ、Facadeパターン
- 複雑な機能へのアクセスを簡素化
- データベース
- レイヤードアーキテクチャ、プラグインアーキテクチャ
- レイヤードアーキテクチャでは、クエリ処理、最適化、ストレージエンジンなどが異なる層に分離されている
- プラグインアーキテクチャでは、ストレージエンジンやインデックス機能などがプラグインとして提供されている
- ミドルウェア
- サービス指向アーキテクチャ(SOA)、メッセージ駆動型アーキテクチャ
- 異なるシステムを連携させるため、SOAが適している
- システム間の時間的な依存性を減らすために非同期通信を行うため、メッセージ駆動型アーキテクチャが適している
- パーサー/ジェネレーター/make
- パイプ&フィルターパターン、Visitorパターン
- 入出力の変換処理に特化
- プログラミング言語
- Interpreterパターン
- 形式言語理論に基づいた設計が見られる
- 3D/グラフィックス/メディア
- ドメインの選定基準の根拠を示すためには、アーキテクチャに基づいてシステムを分類した論文を調べる必要がある
- Qualitas Corpusについての論文中では、以下のドメインからシステムを選んだと述べられている
来週の計画¶
- マーティン・ファウラーのリファクタリング本の続きを読み、具体的なリファクタリングパターンについての理解を深める
- Qualitas Corpusのソースコードを対象に、CheckstyleとSonarQubeによる静的解析を実行
- SonarQubeのルールセットのうち、保守性に関するルールを調査
- 異常検出アルゴリズム(Zスコア、CUSUM、Isolation Forest、LOF、One-Class SVM)をコードの保守性分析に適用するための具体的な実装方法を検討