ソフトウェアメトリクスと メソッド内の構造を用いた リファクタリング支援手法の提案

Slides:



Advertisements
Similar presentations
背景 ソフトウェアの大規模化・複雑化 生産性と品質の向上 ↓ オブジェクト指向分析設計の適用 開発ツールの投入.
Advertisements

Myoungkyu Song and Eli Tilevich 発表者: 石尾 隆(大阪大学)
情報伝播によるオブジェクト指向プログラム理解支援の提案
アクセス修飾子過剰性の変遷に着目したJavaプログラム部品の分析
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
Object Group ANalizer Graduate School of Information Science and Technology, Osaka University OGAN visualizes representative interactions between a pair.
リファクタリングのための 変更波及解析を利用した テスト支援ツールの提案
メソッド名とその周辺の識別子の 相関ルールに基づくメソッド名変更支援手法
動的スライスを用いたバグ修正前後の実行系列の差分検出手法の提案
ソースコードに対する適用可能な修正手順を 可視化するリファクタリング支援手法の提案
CKメトリクスを用いてリファクタリングの 効果を予測する手法の提案
ストップウォッチの カード ストップウォッチの カード
ソースコードの変更履歴における メトリクス値の変化を用いた ソフトウェアの特性分析
静的情報と動的情報を用いた プログラムスライス計算法
細かい粒度でコードの再利用を可能とするメソッド内メソッドのJava言語への導入
同一メソッド内に含まれる ブロック間の結合度を用いた メソッド分割手法の提案
コードクローンに含まれるメソッド呼び出しの 変更度合の分析
コードクローンに含まれるメソッド呼び出しの 変更度合の調査
ソフトウェアデザイン工学 EPMの適用結果報告
細かい粒度で コードの再利用を可能とする メソッド内メソッドと その効率の良い実装方法の提案
ソードコードの編集に基づいた コードクローンの分類とその分析システム
東京工科大学 コンピュータサイエンス学部 亀田弘之
オブジェクト指向 プログラミング 第十三回 知能情報学部 新田直也.
暗黙的に型付けされる構造体の Java言語への導入
コードクローンの分類に基づいた メソッド引き上げ手順の提案とその有効性評価
リファクタリング中に生じる コンパイルエラーの自動解消手法
ポインタ解析におけるライブラリの スタブコードへの置換の効果
オブジェクト指向プログラムにおける エイリアス解析手法の提案と実現
動的スライスを用いたバグ修正前後の実行系列の差分検出手法
CKメトリクスに基づくリファクタリングの 効果予測手法の提案と実装
変数のデータフローを考慮した API利用コード例の検索 井上研究室 竹之内 啓太.
利用関係に基づく類似度を用いたJavaコンポーネント分類ツールの作成
Javaプログラムの変更を支援する 影響波及解析システム
社会シミュレーションのための モデル作成環境
コードクローン検出ツールを用いた ソースコード分析システムの試作と プログラミング演習への適用
リファクタリング支援のための コードクローンに含まれる識別子の対応関係分析
ソースコードの特徴量を用いた機械学習による メソッド抽出リファクタリング推薦手法
コードクローンの動作を比較するためのコードクローン周辺コードの解析
UMLモデルを対象とした リファクタリング候補検出の試み
コードクローン検出に基づくデザイン パターン適用支援手法の提案と実現
アルゴリズムとデータ構造1 2005年6月24日
プログラム理解におけるThin sliceの 統計的調査による有用性評価
コードスメルの深刻度がリファクタリングの実施に与える影響の実証的研究
コード片に共通した特性を自動抽出する ソースコード閲覧ツールの試作
○ 後藤 祥1,吉田 則裕2 ,井岡 正和1 ,井上 克郎1 1大阪大学 2奈良先端科学技術大学院大学
コードクローンの理解支援を目的としたコードクローン周辺コードの解析
コードクローン分類の詳細化に基づく 集約パターンの提案と評価
既存ソフトウェア中の 頻出コード片を用いた コード補完手法の提案
コーディングパターンの あいまい検索の提案と実装
JavaScriptを含んだHTML文書に対する データフロー解析を用いた構文検証手法の提案
コードクローン間の依存関係に基づく リファクタリング支援環境の実装
コードクローンの分布情報を用いた特徴抽出手法の提案
オブジェクトの協調動作を用いた オブジェクト指向プログラム実行履歴分割手法
プログラムスライスを用いた凝集度メトリクスに基づく 類似メソッド集約候補の順位付け手法
保守請負時を対象とした 労力見積のためのメトリクスの提案
コードクローン間の依存関係に基づく リファクタリング支援手法の提案と実現
クローン検出ツールを用いた ソフトウェアシステムの類似度調査
オープンソースソフトウェアに対する コーディングパターン分析の適用
コードクローン間の依存関係に基づく リファクタリング支援手法の提案と実現
ソフトウェア理解支援を目的とした 辞書の作成法
エイリアス関係を考慮した Javaプログラム用静的スライシングツール
複雑度メトリクスを用いた JAVAプログラム品質特性の実験的評価
動的スライスを用いたバグ修正前後の実行系列の差分検出手法の提案
動的スライスを用いたバグ修正前後の実行系列の差分検出手法の提案
コードクローン解析に基づく デザインパターン適用候補の検出手法
回帰テストにおける実行系列の差分の効率的な検出手法
メソッド抽出リファクタリングが 行われるメソッドの特徴調査
オブジェクト指向言語における セキュリティ解析アルゴリズムの提案と実現
識別子の読解を目的とした名詞辞書の作成方法の一試案
Presentation transcript:

ソフトウェアメトリクスと メソッド内の構造を用いた リファクタリング支援手法の提案 大阪大学 M2 三宅達也

研究概要 リファクタリングプロセスの一部を自動化する手法の提案 ⇒ 効率的かつ適切なリファクタリングを支援 ソフトウェアメトリクス メソッド内の構造 変数の宣言、参照位置  ⇒ 効率的かつ適切なリファクタリングを支援 SIGSS

発表の流れ 背景 提案手法 評価実験 関連研究 まとめと今後の課題 SIGSS

リファクタリング リファクタリングとは? リファクタリングの効果は? ソフトウェアの外部的振る舞いを保ったまま,内部の構造を改善する技術 ソフトウェアの保守性が増し,後の保守作業効率が向上する SIGSS

リファクタリングプロセス Step 1: リファクタリングを適用すべきコード(Bad Smell)を特定 長すぎるメソッド 複雑な制御構造 Step 2: どのようなリファクタリングを適用すべきかを決定 既存の研究で様々なリファクタリングパターンが提案 Step 3: 適用するリファクタリングの効果を予測 Step 4: プログラムの修正 Step 5: 修正されたプログラムが正しく動作するかテスト SIGSS

リファクタリングの問題点と本研究の目的 手動リファクタリングの問題点 研究目的 Bad Smellの特定や適用すべきリファクタリングパターンの決定には豊富な知識と経験が必要 時間と手間が大きい 誤りが混入しやすい 研究目的 リファクタリングプロセスの一部を自動化し、リファクタリングのコストを削減するための手法を提案 SIGSS

提案手法の概要 リファクタリングすべきコードを検出 適用すべきリファクタリングパターンを特定 リファクタリングの効果を測定 検出対象 : メソッド内のコードの一部 複雑度メトリクスの高い部分 同一の機能に関連する範囲を識別 適用すべきリファクタリングパターンを特定 変数やメソッドの利用状況から特定 Extract Method Move Method Pull Up Method リファクタリングの効果を測定 複雑度メトリクスの変化で評価 SIGSS

メソッド抽出リファクタリング メソッドの一部を新しいメソッドとして抽出 普遍的で頻繁に行われるリファクタリングパターン 対象 長すぎるメソッド 複雑な制御構造をもつメソッド 効果 再利用性の向上 適切な命名を行うことで内部の処理の可読性が向上 拡張性の向上 普遍的で頻繁に行われるリファクタリングパターン ⇒自動化の効果が大きい 再利用性の向上 ↓ 重複コード生成の防止 開発コストの削減 可読性のコード メソッドが何をしているのかメソッド名のみでわかる 呼び出し側のメソッドをコメント列のようによめる SIGSS

提案手法の概要 リファクタリングすべきコードを検出 適用すべきリファクタリングパターンを特定 リファクタリングの効果を測定 検出対象 : メソッド内のコードの一部 複雑度メトリクスの高い部分 同一の機能に関連する範囲を識別 適用すべきリファクタリングパターンを特定 変数やメソッドの利用状況から特定 Extract Method Move Method Pull Up Method リファクタリングの効果を測定 複雑度メトリクスの変化で評価 SIGSS

複雑度メトリクスを用いたBad Smellの検出 メソッド単位だけでなく,ブロック分単位で計測 メトリクス値の悪いブロック分を検出 複雑度を測る際に利用するメトリクス サイクロマチック数 値が大きいほど制御構造が複雑 制御文の条件式の数 + 1 LOC(Lines Of Code) メソッド内の占有率 LVA(Local Variable Availability) SIGSS

ローカル変数のカプセル化 ⇒ 使用しない変数へのアクセスを制限 他クラスで使用しない属性を隠蔽することによって保守性を向上 フィールドをprivate宣言 必要なフィールドに対してのみアクセサメソッドを作成 フィールドのカプセル化 メソッドの場合も、使用しないローカル変数を隠蔽すれば保守性の向上が見込める メソッドの一部を新規メソッドとして抽出 必要なローカル変数のみ引数や返り値を利用してアクセス ローカル変数のカプセル化 ⇒ 使用しない変数へのアクセスを制限 SIGSS

ローカル変数のカプセル化の例 int drawText(Graphics g, int x, int y, int p0, int p1) { int returnVal = super.drawText(g, x, y, p0, p1); String token = null; int toknePos = p0; String buffer = getDocument.getText(p0, p1); LangHighlight lang = getLangHighlight(); StringTokenizer tokens = null; if(lang== LangHighlight.JAVA) toknes = new StringTokenizer(buffer, “…”, true); else if(lang == LangHighlight.COBOL) tokens = new StringTokenizer(buffer, “…”, true); else ・ (省略) return returnVal; } int drawText(Graphics g, int x, int y, int p0, int p1) { int returnVal = super.drawText(g, x, y, p0, p1); String token = null; int toknePos = p0; String buffer = getDocument.getText(p0, p1); StringTokenizer tokens = getTokens(buffer); ・ (省略) return returnVal; } StringTokenizer getTokens(String buffer) { LangHighlight lang = getLangHighlight(); StringTokenizer tokens; if(lang== LangHighlight.JAVA) toknes = new StringTokenizer(buffer, “…”, true); else if(lang == LangHighlight.COBOL) tokens = new StringTokenizer(buffer, “…”, true); else return tokens; drawText内の変数に 返り値を利用して代入 drawText内の変数は 引数として参照 可視変数数:10, 使用変数数:3 メソッドdrawText内で可視な変数の数: 9 可視変数数:3, 使用変数数:3 (可視であった変数の7/10が不可視) メソッド抽出 メソッドdrawText内で可視な変数の数: 10 SIGSS

提案手法の概要 リファクタリングすべきコードを検出 適用すべきリファクタリングパターンを特定 リファクタリングの効果を測定 検出対象 : メソッド内のコードの一部 複雑度メトリクスの高い部分 同一の機能に関連する範囲を識別 適用すべきリファクタリングパターンを特定 変数やメソッドの利用状況から特定 Extract Method Move Method Pull Up Method リファクタリングの効果を測定 複雑度メトリクスの変化で評価 SIGSS

変数を用いた機能の抽象化 メソッドの機能:コード内に現れる変数の値を決定する計算 ⇒メソッドMの機能をF(M)とすると コード内の特定の機能はその機能に対応する変数で表すことができる[1] ⇒メソッドMの機能をF(M)とすると [1]丸山.基本ブロックスライシングを用いたメソッド抽出リファクタリング. 情報処理学会論文誌43(6):1625-1637, Jun 2002. SIGSS

変数を用いた機能の抽象化例 void METHOD() { VAR v1, v2, v3; …………………………… BLOCK1 { } BLOCK3 { v5 = v1 + 4; v5 = v1 + v2 SIGSS

抽象化された2つの機能の類似度 共通要素が小さいほうの機能を占める割合 類似度が高いとき2つの機能は同一の機能である可能性が高い 1つのメソッドにまとめるべき 共通要素の数 小さいほうの機能の要素数 SIGSS

垂直の関係と水平の関係とは 垂直の関係 水平の関係 sample ( ) while while if for if public void sample ( ) { int i = 0; String str; while( hoge() ) { str = “string”; if( jar( I ) ) { make(str); } foo(i); for( int j = 0; j < I ; j++) { sam( i ); if( log ) { System.out.println(i); ・ while( ) { bar(i); sample ( ) while while if for 水平の関係 垂直の関係 if SIGSS

ブロック文の水平結合 水平の関係にあるブロック文間の結合度 水平結合度が閾値以上 水平の関係にあるブロック文の機能の類似度 B1とB2が水平の関係にある時 水平結合度が閾値以上 2つのブロック文は1つのメソッドとして抽出すべき SIGSS

ブロック文の垂直結合 垂直の関係にあるブロック文間の結合度 垂直結合度が閾値以上 内側のブロック文  の機能と  をメソッド抽出した後に残る外側のブロック文   の機能の類似度 垂直結合度が閾値以上 内側のブロック文だけでなく外側のブロック文ごとメソッド抽出すべき SIGSS

ブロック文の垂直結合例 void METHOD() { …………………………… BLOCK1 { VAR v1,v2,v3,v4; } void METHOD() { …………………………… BLOCK1 { VAR v1,v2,v3,v4; newMETHOD(v1,v2); } void newMethod(VAR v1, VAR v2) { BLOCK2 { VAR v5,v6 v5 = v1 + v2; v6 = v1 + v5; SIGSS

同一機能に属するブロック文群識別アルゴリズム RESULT = NULL B = 特定されたブロック文 HCB = B と結合しているブロック文群(Bを含む) NHCB = B と水平結合していないブロック文群 OB = Bの外側のブロック文 if ( NHCB が空でない) if ( VC( OB, HCB ) > VC( OB, NHCB ) ) NHCBを新規メソッドとして抽出 else HCBを新規メソッドとして抽出 EXIT end if if ( OBとHCBが垂直結合している ) if ( OBがメソッド全体でない ) B = OB GOTO 行3 SIGSS

同一機能に属するブロック文群識別の例 void METHOD() { VAR v1, v2, v3, v4, v5; …………………………… BLOCK1 { BLOCK2 { VAR v8 = v1 + v2; v6 = v3 + v8; v7 = v4 + v8; } VAR v9 = 0; BLOCK3 { v9 = v1 + v2 + v6; v5 = v7 + v9 BLOCK4 { BLOCK5 { VAR v12, v13, v14; v10 = v12 + v13 + v14; SIGSS

評価実験 対象言語: Java 対象ソフトウェア 評価基準 高品質なソフトウェア 低品質なソフトウェア バージョンの異なるソフトウェア JHotDraw 低品質なソフトウェア 学生の書いたプログラムなど バージョンの異なるソフトウェア 評価基準 Bad smellの自動特定の妥当性 同一の機能に含まれる範囲識別の妥当性 適用すべきリファクタリングパターンの自動決定の妥当性 Next, I talk about our experiment. Target language is java. Target software is high-quality software such as JHotDraw and low quality software such as programs written by undergraduate students. If quality of target software is good, it is highly possible that there are few candidates of refactoring that are identified by our method. On the contrary, if quality of the target software is low, our method will identify many candidates of refactoring. Evaluation standards are adequacy of automatic identification of the spot should be refactored, adequacy of automatic determination of the applied refactoring and change of complexity metrics value. These experiments are under way SIGSS

適用例 抽出元メソッド 不吉な匂い(if1) If1,for3,for4が同一の機能 サイクロマチック数 12 行数 LVA 0.233 主観的判断 コードコメント 再利用可能な機能的単位 for3 for4 As a preliminary case study, we applied our method to a program written by a undergraduate student. In the interest of saving time, I show only one code fragments indentified by our method. This figure represent the code fragment, in this code fragment our method identified this “for-statement” and the surrounding code that are highlighted in gray as the target of “extract method”. In this “for-statement”, the number of available outer variables is 13, however, the number of really used outer variables is only 3. That means the vertical coupling between this “for-statement” and the outer block statement is low. So, it is easy to extract this “for-statement” from the outer block statement. In addition, there is no outer variable that is referenced in both this “for-statement” and the upper “for-statement”. That means the horizontal coupling between this “for-statement” and the upper “for-statement” is low. So, the upper “for-statement” is also not included in the extracted part. We think this identification is adequate also from a functional standpoint because of the code comments in the place. if1 SIGSS

関連研究 Eclipseのリファクタリング機能 基本ブロックスライシングによるメソッド抽出 Murphy-Hillらの研究 コード修正(リファクタリングプロセス4)の自動化 本手法と組み合わせることが可能 基本ブロックスライシングによるメソッド抽出 変数を1つ指定し,影響範囲をメソッドとして抽出 メソッドの機能は複数の変数を用いた計算により成立 絡み合ったコードを分割することができる Murphy-Hillらの研究 リファクタリングツール作成のガイドライン 軽快なツール 例外的なフォーマットへの対応 特定のタスクに特化した機能 SIGSS

まとめと今後の課題 まとめ 今後の課題 リファクタリングプロセスの一部を自動化するリファクタリング支援手法を提案した ソフトウェアメトリクス ローカル変数のカプセル化 LVA 機能の抽象化 今後の課題 適用実験による定量的な評価 LVAとバグの相関調査 SIGSS