CKメトリクスを用いてリファクタリングの 効果を予測する手法の提案

Slides:



Advertisements
Similar presentations
シーケンス図の生成のための実行履歴圧縮手法
Advertisements

背景 ソフトウェアの大規模化・複雑化 生産性と品質の向上 ↓ オブジェクト指向分析設計の適用 開発ツールの投入.
JavaによるCAI学習ソフトウェアの開発
情報伝播によるオブジェクト指向プログラム理解支援の提案
研究の背景 コードクローン ソースコード中に存在する一致または類似したコード片
リファクタリングのための 変更波及解析を利用した テスト支援ツールの提案
ソースコードに対する適用可能な修正手順を 可視化するリファクタリング支援手法の提案
プログラム実行履歴を用いたトランザクションファンクション抽出手法
プログラム実行時情報を用いたトランザクションファンクション抽出手法
メトリクス計測 プラグインプラットフォームMASUの開発
ソースコードの変更履歴における メトリクス値の変化を用いた ソフトウェアの特性分析
静的情報と動的情報を用いた プログラムスライス計算法
細かい粒度でコードの再利用を可能とするメソッド内メソッドのJava言語への導入
オブジェクト指向プログラムのための 動的結合メトリクスの評価
コードクローンに含まれるメソッド呼び出しの 変更度合の分析
細かい粒度で コードの再利用を可能とする メソッド内メソッドと その効率の良い実装方法の提案
暗黙的に型付けされる構造体の Java言語への導入
コードクローンの分類に基づいた メソッド引き上げ手順の提案とその有効性評価
リファクタリング中に生じる コンパイルエラーの自動解消手法
オブジェクト指向プログラムにおける エイリアス解析手法の提案と実現
シーケンス図を用いて実行履歴を可視化するデバッグ環境の試作
CKメトリクスに基づくリファクタリングの 効果予測手法の提案と実装
ソフトウェアを取り巻く環境の変化がメトリクスに及ぼす影響について
クローンセットに対する主要編集者の分析法の提案と調査
Javaプログラムの変更を支援する 影響波及解析システム
プログラム動作理解支援を目的とした オブジェクトの振舞いの同値分割手法
ソフトウェア設計検証 研究室の紹介 知能情報学部 准教授 新田直也.
動的データ依存関係解析を用いた Javaプログラムスライス手法
ソースコードの特徴量を用いた機械学習による メソッド抽出リファクタリング推薦手法
コードクローンの動作を比較するためのコードクローン周辺コードの解析
UMLモデルを対象とした リファクタリング候補検出の試み
コードクローン検出に基づくデザイン パターン適用支援手法の提案と実現
プログラム理解におけるThin sliceの 統計的調査による有用性評価
バイトコードを単位とするJavaスライスシステムの試作
コードスメルの深刻度がリファクタリングの実施に与える影響の実証的研究
ソフトウェア保守のための コードクローン情報検索ツール
コードクローンの理解支援を目的としたコードクローン周辺コードの解析
コードクローン分類の詳細化に基づく 集約パターンの提案と評価
コーディングパターンの あいまい検索の提案と実装
JAVAバイトコードにおける データ依存解析手法の提案と実装
JavaScriptを含んだHTML文書に対する データフロー解析を用いた構文検証手法の提案
コードクローン間の依存関係に基づく リファクタリング支援環境の実装
オブジェクトの協調動作を用いた オブジェクト指向プログラム実行履歴分割手法
プログラムスライスを用いた凝集度メトリクスに基づく 類似メソッド集約候補の順位付け手法
設計情報の再利用を目的とした UML図の自動推薦ツール
保守請負時を対象とした 労力見積のためのメトリクスの提案
コードクローン間の依存関係に基づく リファクタリング支援手法の提案と実現
アスペクト指向言語のための視点に応じた編集を可能にするツール
プログラムの差分記述を 容易に行うための レイヤー機構付きIDEの提案
クローン検出ツールを用いた ソフトウェアシステムの類似度調査
オープンソースソフトウェアに対する コーディングパターン分析の適用
メソッドの同時更新履歴を用いたクラスの機能別分類法
コードクローン間の依存関係に基づく リファクタリング支援手法の提案と実現
UMLモデルを対象とした リファクタリング候補検出手法の提案と実現
欠陥検出を目的とした類似コード検索法 吉田則裕,石尾隆,松下誠,井上克郎 大阪大学 大学院情報科学研究科
オブジェクト指向開発における フォールト発生早期予測手法の 一提案
エイリアス関係を考慮した Javaプログラム用静的スライシングツール
複雑度メトリクスを用いた JAVAプログラム品質特性の実験的評価
プログラムの一時停止時に 将来の実行情報を提供するデバッガ
コードクローン解析に基づく デザインパターン適用候補の検出手法
メソッド抽出リファクタリングが 行われるメソッドの特徴調査
木構造の比較に基づく メソッド呼び出し履歴の変化の可視化手法
オブジェクト指向言語における セキュリティ解析アルゴリズムの提案と実現
識別子の読解を目的とした名詞辞書の作成方法の一試案
オブジェクト指向メトリクスを用いた 開発支援に関する研究 --- VC++とMFCを用いた開発を対象として ---
プログラム理解のための 付加注釈 DocumentTag の提案
プログラム依存グラフを用いた ソースコードのパターン違反検出法
オブジェクト生成の観測に基づく プログラム実行の要約の抽出
コードクローンを対象とした リファクタリングの有効性に関する調査
Presentation transcript:

CKメトリクスを用いてリファクタリングの 効果を予測する手法の提案  井上研究室  博士前期課程2年 松本義弘

研究の背景 将来的なソフトウェアの保守コストの削減を目的に,リファクタリング[1]と呼ばれる技術が研究されている リファクタリングとは? ソフトウェアの外部的振る舞いを保ったまま,内部の構造を改善する技術 リファクタリングの効果は? ソフトウェアの保守性が向上する リファクタリングを実施するプロセスで,その効果を予測したいという要求がある まず,研究の背景ですが,将来的なソフトウェアの保守コストの削減を目的に,リファクタリングと呼ばれる技術が研究されています. リファクタリングとは,ソフトウェアの外部的振る舞いを保ったまま,内部の構造を改善する技術のことであり,リファクタリングを適用することで,ソフトウェアの保守性が向上すると言われています. また,リファクタリングを実施するプロセスで,その効果を予測したいという要求があります. 次に,一般的に用いられているリファクタリングのプロセスを紹介します. [1] M. Fowler, Refactoring: improving the design of existing code, Addison Wesley, 1999.

研究対象と目的 一般的に使われるリファクタリングプロセス[2] フェーズ1: どこにリファクタリングを適用すべきか決定する フェーズ2: どのようなリファクタリングを適用すべきかを決定する フェーズ3: リファクタリングの効果を予測する フェーズ4: プログラムを修正する フェーズ5: プログラムが正しく動作するかテストする 一般的に用いられているリファクタリングプロセスは,フェーズ1~5の5段階に分かれています. フェーズ1で,どこにリファクタリングを適用するか,フェーズ2でどのようなリファクタリングを適用すべきかを決定します. フェーズ3で,決定したリファクタリングの効果を予測し,フェーズ4では,実際にプログラムを修正します. 最後のフェーズ5では,修正したプログラムが正しく動作するかのテストを行います. 本研究では,フェーズ3リファクタリングの効果予測を支援することを目的とします. [2] T Mens and T. Tourwé. A survey of software refactoring. IEEE Trans. Softw. Eng., 30(2):126–139, 2004.

関連研究 リファクタリング位置特定/選択手法 リファクタリングの効果計測手法 構造的な欠陥(低凝集・高結合のクラスなど)を発見し,それに対して効果的なリファクタリングを提案[3] リファクタリングの効果計測手法 高結合を解消するリファクタリングを,独自に定義した結合度メトリクスに基づいて定量的に評価する[4] 関連研究としましては,リファクタリングの位置特定手法と選択手法があります. 具体的には,低凝集・高結合といった構造的な欠陥をもつクラスを発見し,それに対して効果的なリファクタリングを提案しています. また,リファクタリングの効果を計測する手法としましては, 高結合を解消するリファクタリングを独自に定義した結合度メトリクスに基づいて定量的に評価するものがあります. [3]秦野, 乃村, 谷口, 牛島. ソフトウェアメトリクスを利用したリファクタリングの自動化支援機構. 情報処理学会論文誌,44(6):1548–1557, Jun 2003. [4]Y. Kataoka. T. Imai, H.Andou and T. Fukaya, A quantitative evaluation of maintainability enhancement by refactoring., In ICSM ’02, p. 576-585, 2002.

研究の概要 関連研究の問題 研究目的 リファクタリングは,高結合・低凝集なクラスだけが対象ではない 「計算処理を行うクラスに画面描画の機能の一部が実装されているので適切なクラスに移動したい」 このようなケースにおいても,リファクタリングを評価する必要がある リファクタリング適用支援ツールを使っても,ソースコードの修正はコストがかかる ソースコードを修正する前に,ソフトウェアの保守性に与える効果を知るべき 研究目的 ソースコードを修正する前に,リファクタリングが保守性に与える効果を予測する手法を提案・実装し,有用性を評価する これらの関連研究の問題としましては,リファクタリングは,高結合・低凝集なクラスだけが対象ではないということが挙げられます. 例えば, 「計算処理を行うクラスに画面描画の機能の一部が実装されているので適切なクラスに移動したい」というケースがあります. このようなケースにおいても,リファクタリングを評価する必要があります. また,リファクタリング適用支援ツールを使っても,ソースコードの修正はコストがかかるため,ソースコード修正前にソフトウェア 保守に与える効果を知るべきだと考えています. そこで,本研究の目的は,ソースコードを修正する前に,リファクタリングが保守性に与える効果を予測する手法を提案・実装し, 有用性を評価することです. 次にソフトウェアの保守性に関連する研究を紹介します.

ソフトウェアの保守性 「機能仕様の変更や追加に対する修正のしやすさ」を表す ソフトウェアの保守性を評価するためにソフトウェア複雑度メトリクスが用いられている[4]. メトリクスが高く複雑であればあるほど修正のコストがかかり,保守が困難であると評価されている 代表的なソフトウェア複雑度メトリクスとして,CKメトリクスがあげられる 次にソフトウェアの保守性に関して簡単に紹介します. ソフトウェアの保守性とは, 「機能仕様の変更や追加に対する修正のしやすさ」を表します. また,ソフトウェアの保守性を評価するために,ソフトウェア複雑度メトリクスが用いられます. ソフトウェア複雑度メトリクスが高く複雑であればあるほど修正のコストがかかり,保守が困難であると評価されています. 代表的なソフトウェアメトリクスとして,CKメトリクスがあげられます. [4] 神谷年洋, オブジェクト指向メトリクスを用いた開発支援法に関する研究, PhD thesis, 大阪大学大学院基礎工学研究科, 2001.

※これらのメトリクスは,値が高いほどクラスが複雑であることを表す CKメトリクス CKメトリクスは以下の3つの観点からクラスの複雑さを評価する 継承 DIT (Depth of inheritance tree) NOC (Number of children) 結合 RFC(Response for a class) CBO(Coupling between object-class) クラスの 内部複雑度 WMC(Weighted methods per class) LCOM(Lack of cohesion in method) CKメトリクスは継承,結合,クラスの内部複雑度の3つの観点,6つのメトリクスからクラスの複雑さを評価します. また,これらのメトリクスは,値が高いほどクラスが複雑であることを表します. 本研究では,CK メトリクスを用いてリファクタリングがソフトウェア保守に与える効果を予測する手法を提案します ※これらのメトリクスは,値が高いほどクラスが複雑であることを表す 本研究では,CK メトリクスを用いてリファクタリングがソフトウェアの保守性に与える効果を予測する手法を提案

提案手法の概要 プログラム解析 解析情報α CK Metricsα 解析情報α’ CK Metricsα’ STEP1 ユーザ STEP2 リファクタリング箇所とパターンを取得 ユーザ リファクタリング前後のメトリクスの変化率の計算 STEP4 解析情報α’ STEP3 次に提案手法の概要について説明します. まず初めに,ユーザーによって与えられたプログラムを解析し,解析情報を取得します. そして,取得した解析情報を基にCKMetricsを計測します. 次に,ユーザはリファクタリングしたい箇所とリファクタリングパターンを与えます. そして,与えられたリファクタリング箇所とパターンを基に,解析情報の修正を行います. 最後に,修正された解析情報からCKメトリクスを計測し,リファクタリング前後のメトリクスの変化率をユーザにフィードバックするといった流れになっています. 次に,このSTEP1から4に関して,詳しく説明していきます. CK Metricsα’

STEP1:対象プログラムの解析 対象プログラムの解析を行い,CKメトリクスを計測する CKメトリクス計測 解析情報 ソフトウェアを構成する全クラス 解析情報  ・クラス間の参照関係  ・メソッド間の参照関係  ・メソッドとフィールドの参照関係  ・メソッド内の分岐・繰り返しの数  など D B A C E まず,STEP1では,対象プログラムの解析を行い,CKメトリクスの計測を行います. 解析して得られる情報としましては, ・クラス間の参照関係 ・メソッド間の参照関係 ・メソッドとフィールドの参照関係 ・メソッド内の分岐と繰り返しの数 などが挙げられます. これらの情報を元に,CKメトリクスの計測を行います. F G CKメトリクス計測

STEP2:リファクタリング箇所とリファクタリングパターンの入力 リファクタリングしたい箇所(フィールド,メソッド,クラス)を指定し,適用したいリファクタリングパターンを与える 実装しているリファクタリングパターン フィールドの移動 フィールドの引き上げ フィールドの引き下げ メソッドの移動 メソッドの引き上げ メソッドの引き下げ クラスの抽出 スーパークラスの抽出 サブクラスの抽出 次にSTEP2ですが,ユーザはリファクタリングしたい箇所,フィールド,メソッド,クラスを指定し,適用したいリファクタリングパターンをシステムに与えます. 本研究で実装しているリファクタリングパターンはこの9つで,構造的な変化を伴うリファクタリングパターンの一部を実装しています.

STEP3:解析情報の修正(1) STEP2を元に解析情報を修正する 例:クラスAのメソッドa1()をクラスBへ移動 (1)リファクタリングの影響を受けるクラスを検出する (2)ユーザ非依存部分の修正 (3)ユーザ依存部分の修正 D B クラス メソッド Fan-in A a1() B b1() C c1() D d1() a2() ・・・ d1( ) call a1( ) b1( ) call a1( ) STEP2で入力された情報をもとに,解析情報を修正します. ここで,クラスAのメソッドa1()をクラスBへ移動するという例を用いて説明します. メソッドa1()は,メソッドb1,c1,d1から参照されているとすると,メソッドb1,c1,d1が属するクラスB,C,Dが影響を受けるクラスとなります. A a1( ) a2( ) C call a1( ) c1( )

STEP3:解析情報の修正(2) STEP2を元に解析情報を修正する (ClassB)a1() 例:クラスAのメソッドa1をクラスBへ移動 (1)リファクタリングの影響を受けるクラスを検出する (2)ユーザ非依存部分の修正 (3)ユーザ依存部分の修正 クラス メソッド A a2() クラス メソッド B b1() D B a1() d1( ) call a1( ) a1() b1( ) a1( ) 次に,解析情報の修正を行います. 解析情報の修正は,ユーザ非依存部分とユーザ依存部分の2段階に分けられます. ユーザ非依存部分の修正は,システムが機械的に変換できるものに限られます. 例えば,メソッドa1()はクラスAに属しているという情報をクラスBへ移動すること, また,メソッドb1()がクラスAを参照していたのをクラスB自身の参照に変換するといった処理です. メソッドb1() Offset 命令 10 (ClassA)instA.a1() call a1( ) A a1( ) C ~ a2( ) call a1( ) c1( ) (ClassB)a1()

STEP3:解析情報の修正(3) STEP2を元に解析情報を修正する どのインスタンスに対して呼び出すのか? 例:クラスAのメソッドA1をクラスBへ移動 (1)リファクタリングの影響を受けるクラスを検出する (2)ユーザ非依存部分の修正 (3)ユーザ依存部分の修正 メソッドd1() Offset 命令 20 (ClassA)instA.a1() D B call a1( ) d1( ) a1() b1() ~ 次に,ユーザ依存部分の修正です. メソッドd1()は,元々クラスAを参照していましたが,a1()を移動したため,クラスBに参照先を変更する必要があります. そこで,メソッドd1()内では,メソッドa1()をクラスBのどのインスタンスに対して呼び出すのかを決定しなければなりません. その際,ユーザに入力を求め,得た情報を元にどのインスタンスに対して呼び出すのかを決定します. A (ClassB)???.a1() a2( ) call a1( ) C どのインスタンスに対して呼び出すのか? c1( )

WMCの変化率= SUMWMC(A’, B’, C’, D’)- SUMWMC(A, B, C, D) SUMWMC(A, B, C, D) STEP4:CKメトリクスの計算 修正後の解析情報を元にCKメトリクスを計測 CKメトリクスの変化があったクラスに対し,メトリクスの変化率を計算 ソフトウェアを構成するクラス群 変化があったクラスのCKメトリクス WMC A’ CBO ・・・ xx DIT B’ C’ D’ 合計 D’ A B F A’ B’ C’ D B A F 変化率 xx xx ・・・ xx E STEP4では,修正後の解析情報を元にCKメトリクスの計測を行います. そして,CKメトリクスの変化があったクラスに対し,メトリクスの変化率を計算します. ここで,クラスA,B,C,Dがメトリクスの変化のあったクラスとし,それぞれのメトリクスの変化率を求めます. ダブリューエムシーの変化率は(リファクタリング後のクラスABCDのWMCの合計)-(リファクタリング前のクラスABCDのWMCの合計)をリファクタリング前のクラスABCDのWMCの合計で割ったものです. WMCの変化率= SUMWMC(A’, B’, C’, D’)- SUMWMC(A, B, C, D) SUMWMC(A, B, C, D) F G

適用実験の概要 適用実験の対象 問題点 改善案 GUI Feature Location Visualizer(以下,FLV) クラス数:37 行数:4815行 GUI GVP BP CL FLGVV ExtractPanel ep; setExtractPanel() setStartClass() CP 問題点 GUIの処理と無関係なComponentList(CL)クラスにGUIの処理の一部が実装されている 改善案 そのフィールドとメソッドを以下のいずれかのクラスに移動する case1: FeatureLocationGraphVisualizationViewer(FLGVV)クラス case2: BirdPanel(BP)クラス case3: ComponentPanel(CP)クラス case4: GraphViewPanel(GVP)クラス 適用実験の概要ですが, 実験対象のプログラムとしましては,”Feature Location Visualizer”というソフトウェアを用いました. そのプログラムの規模は,クラス数37,総行数4815行です. 適用実験の対象ソフトウェアの中で, GUIの処理と無関係なComponentListクラスにGUIの処理の一部が実装されているという問題がありました. 具体的には,ExtractPanel型の変数とそれを参照するsetExtractPanelメソッドとsetStartClassメソッドがありました. 改善案としましては,このフィールドとメソッドをGUIの処理を行う FLGVVクラス,BPクラス,CPクラス,GVPクラスのいずれかに移動するという案が挙がりました. そこで,これらのクラスへ移動する4つのケースに対してリファクタリングの効果を予測するという実験を行いました. 次に,case1の結果を示し,その後にcase1-4のメトリクスの変化率の比較を行います.

適用実験の結果(case1) 表1.case1の結果 「フィールド,メソッドの移動」は,継承の変化を伴わないのでNOC,DITは変化しない LCOMは,getter/setterは省いて計測する仕様を採用したため,値に変化がなかった. WMC,CBO,RFCは変化が見られた. WMC:変化なし CBO:減少 RFC:微量な変化 適用実験の結果です. この表は,case1のリファクタリング後のメトリクス値とその値の増減値を括弧の中に載せています. また,青で色づけされているものは,メトリクスが減少し複雑度が改善したもの,赤はメトリクスが増加し悪化したものを表します. さらに,WMCの合計と変化率を緑で色づけしているのは,各クラスのメトリクスに変化が見られたのですが, 合計は変化しなかったということを表しています. 今回適用した,「フィールド,メソッドの移動」は,継承の変化を伴わないのでNOC,DITは変化しませんでした. また,LCOMは,getter/setterは省いて計測する仕様を採用したため,値に変化がなかった. WMC,CBO,RFCは変化が見られた. WMCは,合計に変化がなく,CBOは減少,RFCは微量に増加するという結果が得られました.

適用実験の結果 case1~4で,メトリクスの変化率をクラス数で正規化し,それぞれを比較 case1 case2,3,4 WMCは変化なし RFCは微量な変化 case1 リファクタリング後のCBOの値は減少し,一番良い結果が得られた case2,3,4 リファクタリング後のCBOは増加してしまった 次に,case1-4で,メトリクスの変化率をクラス数で正規化し,それぞれ比較を行いました. この結果から,すべてのcaseにおいて,WMCは変化がなく,RFCは微量な変化という結果が得られました. また,case1においては,リファクタリング後のCBOの値は減少し,他のリファクタリングよりも良い結果が得られました. case2,3,4においては,リファクタリング後のCBOの値は増加してしまうという結果が得られました.

考察 開発者の主観でリファクタリングを行うと,case2,3,4のようなリファクタリングを適用する可能性があり,ソフトウェアが構造的に悪化する危険がある 本手法を用いて比較することは重要である 本手法では,リファクタリング前後のメトリクスの値だけでリファクタリングを評価している より正確に評価するためには,ソースコード修正にかかるコストやテストにかかるコストも考慮するべき 最後に,結果に対して考察です. 開発者の主観でリファクタリングを行うとcase2,3,4の場合を適用してしまう可能性があり,ソフトウェアが構造的に悪化する危険があります. そのため,本手法を用いて比較することは重要であると考えています. また,開発者からは,これらの違いをソースコード修正前に知ることができるのは有益であるとコメントを頂きました. しかし,本手法では,リファクタリング前後のメトリクスの値だけでリファクタリングを評価していますが,より正確に評価するためには,ソースコードの修正にかかるコストやテストにかかるコストも考慮するべきだと考えています.

まとめ まとめ 今後の課題 リファクタリングがソフトウェアの保守性に与える効果を予測する手法を提案した. その手法の適用実験を行い,有用性を評価した. 今後の課題 「クラスのインライン化」など,構造的な変化を伴う未実装なリファクタリングに関しても実装したい ソースコード修正にかかるコスト,テストにかかるコストを考慮し,手法を改良したい 最後にまとめです. (スライドに書いてることを言う)