コードクローン間の依存関係に基づく リファクタリング支援手法の提案と実現 大阪大学 井上研究室 吉田 則裕 2006/3/31 名阪和研究会
コードクローンとは ソースコード中に存在する他のコード片と同一または類似したコード片 コピー&ペーストなどが原因で生じる ソフトウェア保守を困難にする要因の一つ コードクローンとなっているコード片の一つを修正すると,他のコード片も修正の検討を行う必要がある ソースコード ソースコード コードクローン コード片 まず,最初に背景としまして,コードクローンとは何かということについて説明します. コードクローンとは,ソースコード中に存在する同一,もしくは類似したコード片のことで,コピー&ペーストなどによる,プログラム再利用が原因で生じます. また,コードクローンはソフトウェア保守を困難にする要因のひとつです. たとえば,この図のように,ソースコード中や2つのソースコード間でコードクローンが存在するとき,このうちの1つのソースコードを修正すると,他の2つのソースコードについても修正の検討を行う必要があります. コード片 コード片 クローンセット 2006/3/31 名阪和研究会
リファクタリングとは,ソフトウェアの外部的振る舞いを保ったままで,内部の構造を改善していく作業 [1] 重複したコード片(コードクローン)は,優先してリファクタリングすべき対象 将来的な修正コストを削減する コード片 新たに作成したメソッド メソッド 呼び出し文 コード片 コードクローンへの対策として,コードクローンの集約(リファクタリング)が考えられます. リファクタリングとは,ソフトウェアの外部的振る舞いを保ったまま,内部の構造を改善していく作業のことです. リファクタリングの第一人者であるファウラー氏は,彼の著作の中で「重複したコード片,つまりコードクローンは,最も優先してリファクタリングすべきと述べています. また,リファクタリングは将来的な修正コストの削減につながると考えられます. この図は,コードクローンに対するリファクタリングの様子を表しています, この図の左のソースコードのように,3つのコード片がコードクローンとなっている場合,コードクローンを1つのメソッドに集約し,元々コードクローンになっていた部分をそのメソッドの呼び出し文に変更することによってリファクタリングすることができます. コード片 [1] M. Fowler, Refactoring: improving the design of existing code, Addison Wesley, 1999. 2006/3/31 名阪和研究会
コードクローンを対象としたリファクタリング支援 リファクタリングを行うために必要な情報 リファクタリングの検討が必要なソースコードの位置情報 適用可能なリファクタリングパターン これまでに,コードクローンを対象としたリファクタリングに必要な情報を提示するツールを開発 コードクローン検出ツールCCFinder[2] コードクローンの位置情報を出力 リファクタリング支援環境Aries[3] 適用可能なリファクタリングパターンの提示 リファクタリングを行うために必要な情報は2つあります. 1つ目は,リファクタリングの検討が必要なソースコードの位置情報,つまりどの部分にリファクタリングを行うかという情報です. 2つめは,適用可能なリファクタリングパターン,つまりどうやってリファクタリングを行うのかという情報です. 我々の講座では,これまでにコードクローンを対象としたリファクタリングに必要な情報を提示するツールを開発してきました. 1つは,コードクローン検出ツールCCFinderです. これは,コードクローンの位置情報を出力します. もう一つは.リファクタリング支援環境Ariesです. これは,コードクローンに対し,適用可能なリファクタリングパターンを提示します. [2] T. Kamiya, S. Kusumoto, and K. Inoue, “CCFinder: A multi-linguistic token-based code clone detection system for large scale source code”, IEEE Transactions on Software Engineering, 28(7):654-670, 2002. [3] 肥後芳樹, 神谷年洋, 楠本真二, 井上克郎. コードクローンを対象としたリファクタリング支援環境, 電子情報通信学会論文誌D-I, Vol. 88, No. 2, pp. 186–195, 2005. 2006/3/31 名阪和研究会
リファクタリング支援環境Aries 各クローンセットに対して,個別にリファクタリング支援を行う クローンセット1 クローンセット2 リファクタリングパターンの決定支援を目的としたメトリクスを提示 コードクローンの検出に,CCFinderを利用 NRV NSV DCH パターン ∞ Extract Method 1 Pull Up Method クローンセット1 コード片a1 コード片b1 クローンセット2 コード片a2 コード片b2 クローンセット3 コード片a3 コード片b3 2006/3/31 名阪和研究会
クローンセット間の依存関係 (1/2) 異なるクローンセットに含まれるコード片間に依存関係が存在 各クローンセットに対して,個別にリファクタリングを行うことが困難 親クラス メソッド1 親クラス 集約 クラスA クラスB クラスA クラスB メソッドa1 メソッドb1 それでは、本研究の動機について説明します。 ソフトウェア中には、複数のクローンセットをまとめて扱うことにより、効率的なリファクタリングを実現できる場合があります。 この図では、クラスAとクラスBに共通の親クラスが存在し、クラスA中のメソッドa1、クラスB中のメソッドb1がコードクローンとなっており、さらに、メソッドa1から呼び出されるメソッドa2、メソッドb1から呼び出されるメソッドb2もコードクローンとなっています。 このとき、メソッドa1とメソッドb1を親クラスに作成したメソッドに集約しますと、親クラスのメソッドから、メソッドa2もしくは、メソッドb2を呼び出すことができません。 呼出できない 呼出 呼出 メソッドa2 メソッドb2 メソッドa2 メソッドb2 2006/3/31 名阪和研究会
クローンセット間の依存関係(2/2) 呼出先の二つのメソッドもコードクローンであることを利用することにより,まとめてリファクタリングを行うことが可能 リファクタリング技術に詳しく,かつコード片間の依存関係を把握した技術者でなければ,適切にリファクタリングを行うことは困難 リファクタリング支援が必要 親クラス 親クラス メソッド1 呼出 クラスA クラスB メソッド2 しかし、呼び出し先の二つのメソッドもコードクローンですので、それらメソッドも親クラスに集約すると、先ほどの親クラスからサブクラスのメソッドを呼び出せないという問題を解決することができます。 メソッドa1 メソッドb1 呼出 呼出 クラスA クラスB メソッドa2 メソッドb2 2006/3/31 名阪和研究会
本研究の目的 クローンセット間の依存関係を利用したリファクタリング支援手法を提案 異なるクローンセットに含まれるコード片間に依存関係がある場合に着目 そのような依存関係を持つコード片の集合をチェーンドクローンセット として定義 チェーンドクローンセットの特徴に応じて,適用可能なリファクタリングパターンを提示する手法を提案 チェーンドクローンセット コード片a1 コード片b1 コード片1 リファクタリング コード片a2 コード片b2 コード片2 2006/3/31 名阪和研究会
チェーンドクローンセットの定義 複数のクローンセットが与えられたとき,コード片を頂点,依存関係を有向辺とする有向グラフを作成し,連結成分(チェーン)毎に分割する このとき,二つの条件が成り立つなら,それらのチェーンは,チェーンドクローンセットであるという 各チェーンに含まれる頂点が,互いにコードクローン関係で対応をとることができる チェーン上で,有向辺 Ea =(a1, a2)があれば,その他のチェーン上で,a1に対応するb1,a2に対応するb2からなる有向辺 Eb = (b1, b2)が存在する チェーンドクローンセット クローンセット1 コード片a1 コード片b1 呼出 呼出 クローンセット2 コード片a2 コード片b2 呼出 呼出 クローンセット3 コード片a3 コード片b3 2006/3/31 名阪和研究会
チェーンドクローンセットに対するリファクタリング支援 チェーンドクローンセットを,適用可能なリファクタリングパターンにより,四種類に分類する 分類1:Extract Method パターンが適用可能 分類2:Pull Up Method パターンが適用可能 分類3:Extract SuperClassパターンが適用可能 分類4:上記3つのリファクタリングパターンが適用不可能 チェーンドクローンセットを特徴に応じて自動的に分類し,対応するリファクタリングパターンを提示する それでは,チェーンドクローンセットに対するリファクタリングについて説明したいと思います. チェーンドクローンセットを集約するリファクタリングパターンとしてPull Up Method, Extract Method, Extract Super Class利用します. チェーンドクローンセットの特徴に応じて,5種類に分類し,適切なリファクタリングパターンを適用します. この5種類の分類を,分類 1から分類 5と名づけているのですが,時間の都合上,C1とC3の説明のみにさせていただきます. 2006/3/31 名阪和研究会
チェーンドクローンセットの分類 分類 1 : Extract Method パターンが適用可能 特徴 チェーンドクローンセットが一つのクラスに包含されている 集約方法 同一のクラス内に全てのコードクローンを集約 リファクタリング前 リファクタリング後 クラスA クラスA チェーンドクローンセット コード片a1 コード片b1 メソッド1 まず,分類 1ですが,これはチェーンドクローンセットが同一のクラスに含まれている場合です. この図のように,チェーンドクローンセット内に含まれる全てのメソッドが同一のクラスに存在する場合,同一のクラス内に,互いにクローンとなっているメソッドを集約します.この図では,互いにクローンとなっているメソッドa11とa12を集約しメソッド a1とし,同じくクローンとなっているメソッドa21とメソッドa22をメソッドa2に集約します. これは,Extract Method パターンの適用ともいえます. コード片a2 コード片b2 メソッド2 2006/3/31 名阪和研究会
チェーンドクローンセットの分類 分類 2 : Pull Up Method パターンが適用可能 特徴 各チェーンは,それぞれ一つのクラスに包含されている チェーンを含んでいる全てのクラスは,共通の親クラスを持つ 集約方法 全てのコードクローンを共通の親クラスに引き上げる リファクタリング前 リファクタリング後 親クラス 親クラス メソッド1 クラスA クラスB チェーンドクローンセット メソッド2 コード片a1 コード片b1 コード片a2 コード片b2 クラスA クラスB 2006/3/31 名阪和研究会
チェーンドクローンセットの分類 分類 3 : Extract SuperClassパターンが適用可能 特徴 各チェーンは,それぞれ一つのクラスに包含されている チェーンを含んでいる全てのクラスは,共通の親クラスを持たない 集約方法 新たに共通の親クラスを作成して,そのクラスに2つのコードクローンを引き上げる リファクタリング前 リファクタリング後 新たに作成した親クラス クラスA クラスB メソッド1 チェーンドクローンセット コード片a1 リファクタリング後の図をさす 次に,分類 3ですが,これはチェーンドクローンセットが複数のクラス間に分散しており,かつ共通の親クラスを持たない場合です. この場合,関係するクラスに共通の親クラスを新たに作成し,互いにクローンとなっているメソッドを新たに作成したメソッドに集約します.この図の場合,クラスA,B共通の親クラスを作成し,そのクラスに互いにクローンとなっているメソッドa1とb1,メソッドa2とb2を新たに作成した親クラスに集約します. コード片b1 メソッド2 コード片a2 コード片b2 クラスA クラスB 2006/3/31 名阪和研究会
チェーンドクローンセットの分類 分類 4 前述した3つのリファクタリングパターンを適用不可能 チェーンドクローンセットの分類 分類 4 前述した3つのリファクタリングパターンを適用不可能 特徴 各チェーンが,それぞれ複数のクラス間にまたがっている クラス S1 クラス S2 チェーンドクローンセット クラス A クラス B クラス C クラス D コード片a コード片b コード片c コード片d 前述した3つのリファクタリングパターンを適用できない (個々のコードクローンとして,リファクタリングすることはできる) 2006/3/31 名阪和研究会
チェーンドクローンセットの自動分類手法 与えられたチェーンドクローンセットに,どのリファクタリングパターンを適用できるかメトリクスを用いて判定 抽出すべき特徴 クローンセットに含まれるコード片間の関係 チェーンに含まれるコード片間の関係 コード片間の関係を三種類に分けて考える R1:各コード片は同一クラスに所属 R2:各コード片が所属するクラスは同一ではないが,共通の親クラスを持つ R3:各コード片が所属するクラスは共通の親クラスを持たない 親クラス Pull Up Methodパターンを適用するためには,クローンセットに含まれるコード辺間の関係がR2である必要がある クラスA クラスB コード片a1 コード片b1 コード片a2 コード片b2 2006/3/31 名阪和研究会
メトリクスDCH (the Dispersion of Class Hierarchy) 与えられたコード片群と,その共通の親クラスまでの距離の最大値を表す[3] R1:同一クラス R2: 共通の親クラスを 持つ R3: 共通の親クラスを持たない クラスP クラスA クラスB クラスC クラスD クラスE コード片a1 コード片a2 コード片b コード片c コード片d コード片e DCHは1以上の整数 (この例では1) 共通の親クラスに注目して、説明 最大値の距離を赤で示す 例を用いて説明します. まず,左側の例から説明します. これは,クラスA,Bに1つずつメソッドが所属しており,またクラスA,Bには共通の親クラスが存在しているという例です. この場合,DCHは1となります. 次に,右側の例を説明します. これは,クラスA,B,Cに1つずつメソッドが所属しており, またクラスA,Bには共通の親クラスS2,クラスS2,クラスCには共通の親クラスS3が存在しているという例です. この場合,DCHは2となります. DCH = 0 DCH = ∞ [3] 肥後芳樹, 神谷年洋, 楠本真二, 井上克郎. コードクローンを対象としたリファクタリング支援環境, 電子情報通信学会論文誌D-I, Vol. 88, No. 2, pp. 186–195, 2005. 2006/3/31 名阪和研究会
DCHD = max{DCH(C1), …, DCH(Cm)} 自動分類を目的としたメトリクスの定義 DCHS:クローンセットに含まれるコード片間の関係を表す DCHD:チェーンに含まれるコード片間の関係を表す 各チェーンに含まれるコード片に対し,それぞれDCHを求め,その最大値をDCHDとする DCHD = max{DCH(C1), …, DCH(Cm)} 親クラス クラスA クラスB C1 C2 テーブルを作る メトリクスの分類 チェーンドクローンセットがC1~C5のいずれに該当するか決定をするために必要な情報は2つあります. 1つ目は,互いにクローンとなっているメソッドのDCHです. これにより,互いにクローンとなるメソッドの間に共通の親クラスが (2)含まれるフラグメントチェーンのDCH コード片a1 コード片b1 S1 クローンセットに含まれるコード片について,それぞれDCHを求め,その最大値をDCHSとする コード片a2 コード片b2 S2 DCHS = max{DCH(S1), …, DCH(Sn)} 2006/3/31 名阪和研究会
メトリクスによるチェーンドクローンセットの分類 DCHD DCHS (R1) 1以上の整数 (R2) ∞ (R3) Extract Methodが 適用可能 いずれのリファクタリングパターンも 適用不可能 Pull Up Methodが Extract SuperClassが適用可能 Using the two metrics, we classify チェーンドクローンセットs into 9 categories DCHS:クローンセットに含まれるコード片間の関係を表す DCHD:チェーンに含まれるコード片間の関係を表す 2006/3/31 名阪和研究会
適用実験 概要 目的 チェーンドクローンセットの数,規模の調査 適用実験 概要 目的 チェーンドクローンセットの数,規模の調査 メトリクスを用いてチェーンドクローンセットを分類し,その分類に対応したリファクタリングパターンを適用できるか確認 対象 ANTLR 2.7.4 (4.7万行,285クラス) C++, Java, C#用コンパイラ・コンパイラ JBoss 3.2.6 (64万行,3364クラス) J2EE アプリケーションサーバ チェーンドクローンセットに基づくリファクタリング支援ツールを作成 コードクローン検出ツールCCFinderを用いてクローンセットを検出 それらクローンセットに含まれるコード片間の依存関係を解析し,チェーンドクローンセットを検出 定義したメトリクスに基づき,リファクタリングパターンを提示 2006/3/31 名阪和研究会
適用実験 チェーンドクローンセットの検出(ANTLR 2.7.4) 分類 検出数 コード片数 最大 最小 Extract Method 6 11 4 Pull Up Method 8 120 Extract SuperClass 1 いずれも適用不可能 合計 15 全てリファクタリングパターンを適用可能なチェーンドクローンセットであった 提示されたリファクタリングパターンを用いて,全てのチェーンドクローンセットをリファクタリングできた 含まれるコード片数が多いチェーンドクローンセットを検出できた 三つの言語(C++, C#, Java)に対応した部分の多くがコードクローンとなっていたため 合計を先にいう 特徴を言う C5消す 2006/3/31 名阪和研究会
適用実験 チェーンドクローンセットの検出(JBoss 3.2.6) 分類 検出数 コード片数 最大 最小 Extract Method 52 37 4 Pull Up Method 45 35 6 Extract SuperClass 36 29 いずれも適用不可能 8 65 合計 141 ANTLRと比較して,Extract SuperClassパターンが適用可能なチェーンドクローンが多い パッケージ内に複数のソフトウェアを含むため,ソフトウェア間のコードクローンが存在するため 合計を先にいう 特徴を言う C5消す 2006/3/31 名阪和研究会
適用実験 リファクタリング例:Pull Up Methodパターン CodeGenerator CodeGenerator getValueString 呼出 CSharp CodeGenerator Java CodeGenerator mangleLiteral getValueString getValueString 説明を Beforeの方に,Extract Super Classする前のクラスをてんてんで書く 呼出 呼出 CSharp CodeGenerator Java CodeGenerator mangleLiteral mangleLiteral リファクタリング前 リファクタリング後 2006/3/31 名阪和研究会
クローンセット間の依存関係を利用したリファクタリング支援手法を提案 まとめ クローンセット間の依存関係を利用したリファクタリング支援手法を提案 異なるクローンセットに含まれるコード片間の依存関係に着目し,チェーンドクローンセットを定義 チェーンドクローンセットに対する適用可能なリファクタリングパターンを提示するためのメトリクスを定義 適用実験を通じた妥当性の確認 今後の課題 開発現場において,チェーンドクローンセットに対するリファクタリングを行うことにより,保守性を向上できるかの評価 発表会 : 2月20日 2006/3/31 名阪和研究会