コードスメルの深刻度がリファクタリングの実施に与える影響の実証的研究 井上研究室 雜賀 翼 井上研究室の雜賀です. 研究題目は「コードスメルの深刻度がリファクタリングの実施に与える影響の実証的研究」です. よろしくお願いします.
リファクタリング ソフトウェアの外部から見た動作を変えずに, ソースコードを整理する作業[1] クラスやメソッドなどのプログラム要素が対象 外部から見た動作は同じ リファクタリング 理解しにくい ソースコード 理解しやすい ソースコード まずリファクタリングとは, ソフトウェアの外部から見た動作を変えずに, ソースコードを整理する作業のことで, クラスやメンバなどの, プログラム要素を対象に実施されます. 理解しにくいソースコードに対して, 開発者がリファクタリングを実施することで, 理解しやすいソースコードへ変換でき, 機能の追加やバグの修正などがしやすくなります. 機能の追加, バグの修正がしやすい 開発者 [1] M. Fowler. Refactoring:Improving the Design of Existing Code. Addison Wesley,1999.
コードスメル 設計上の問題を持ち, 保守性を悪化させてバグの原因になりやすいクラスやメソッドの特徴 開発者がリファクタリングを実施するべきソースコードの指標として提案された[1] コードスメルの例 コードスメル 説明 推奨されるリファクタリング Blob Class コードが長く複雑なクラス クラスの抽出など Blob Operation コードが長く複雑なメソッド メソッドの抽出など 0:36 また, コードスメルとは, 設計上の問題を持ち, 保守性を悪化させてバグの原因になりやすいクラスやメソッドの特徴のことです.コードスメルは, 開発者がリファクタリングを実施するべきコードの指標として提案されました. 下の表はコードスメルの例を示したものです. Blob Classとは, 他のクラスと比べてコードが長く複雑なクラスのことです. また, Blob Operationはコードが長く複雑なメソッドのことです. [1] M. Fowler. Refactoring:Improving the Design of Existing Code. Addison Wesley,1999.
機能を他のクラスに分割することで, コードの理解がしやすくなる コードスメルの例 Blob Classを含むクラスについて, 推奨されるクラス抽出リファクタリングを実施する例 長さ クラスC クラスC クラスB クラスB 新クラス クラス抽出 クラスを新しく作成し, フィールドとメソッドを移動 クラスA クラスA 1:13 コードスメルの例として, Blob Classを含むクラスについて, 推奨されるクラス抽出リファクタリングを実施する例を紹介します. この図ではクラスの長さを縦の長さで表しています. まず, この赤色で示したBlob Classは他のクラスと比べてコードの行数が大きく, 複雑で理解しにくいという問題があります. これを改善するため, クラスの抽出というリファクタリングを実施し, クラスを新しく作成して, 元のクラスのフィールドとメソッドの一部をそこに移動することで, 理解しやすいクラスへと分割することができます. Blob Class コードの行数が大きく, 複雑で理解しにくい 機能を他のクラスに分割することで, コードの理解がしやすくなる
2つ以上のBlob operationを含む コードスメル検出ツール リファクタリングを実施するべきソースコードの箇所を特定することを目的として利用される コードスメルを自動検出し開発者に提示する 多くのツールは主にメトリクスを用いて検出する 例) Blob Classの検出手法[2] LOC(行数)が非常に高い 1:50 リファクタリングを実施するべきソースコードの箇所を特定することを目的としてコードスメル検出ツールが利用されます. ツールはソースコードからコードスメルを自動検出し開発者に提示します. 多くのツールは主にメトリクスを用いてコードスメルを検出します. 下の図はBlob Classの検出手法を示したものです。 (行数が高いとか複雑度が高いとかといった条件を全て満たしたクラスがBlob Classと判定されます. また、この高いとか低いとかの基準はツールによって異なります. ) WMC(複雑度)が非常に高い AND Blob Class TCC(凝集度)が低い 2つ以上のBlob operationを含む 高い低いの基準はツールにより異なる [2] M. Lanza and R. Marinescu. Object-Oriented Metrics in Practice. Springer, 2006.
コードスメルの深刻度 数値化されたコードスメルの示す問題の大きさ 同じBlob Classでも500行と1000行とでは, 開発者のリファクタリング実施に差があると推測される 各種類のコードスメルについて, 検出に用いるメトリクス値を組み合わせて深刻度は1~10の10段階で測定される 深刻度1が最も軽微で, 深刻度10が最悪 深刻度はメトリクスに求められるWeyukerの性質[3]をCKメトリクスと同様に満足する[4] メトリクス値の大きさからリファクタリング実施対象のソースコードを特定することが行なわれている[5] 2:30 本研究ではコードスメルの示す問題の大きさのことをコードスメルの深刻度と呼びます. 例えば, 同じBlob Classでも500行と1000行とでは問題の大きさに差があるはずで, 開発者のリファクタリングの実施に影響すると推測されます. 各種類のコードスメルについて, 検出に用いるメトリクス値を組み合わせて深刻度を1~10の10段階で測定します. 深刻度1が最も軽微なコードスメルで, 深刻度10が最悪なコードスメルとします. この深刻度はメトリクスに求められる, Weyukerの性質をCKメトリクスと同様に満足する. メトリクス値の大きさからリファクタリング実施対象のソースコードを特定することが既に行なわれています. [3] E. J. Weyuker. Evaluating software complexity measures. IEEE Tans Softw Eng., 1988. [4] S.R. Chidamber et al. A Metrics Suite for Object Oriented Design”, IEEE Trans Softw Eng., 1994. [5] F. Simon et al. Metrics based refactoring. In Proc of CSMR, 2001
研究動機 開発者がリファクタリング実施するコードスメルの基準は明確にされていない 検出ツールと開発者でコードスメルの基準が大きく異なると, 有用なコードスメルを提示できない ツールが検出するコードスメルが, 開発者のリファクタリング実施対象になるか調べる必要がある 3:30 開発者がリファクタリングを実施するコードスメルの基準は明確にされていません. そのため, ツールが検出するコードスメルと, 開発者がリファクタリングを実施するコードスメルとで基準が大きく異なると, ツールは開発者にとって有用なコードスメルを提示できません. この問題に対して, ツールが検出するコードスメルが, 開発者のリファクタリング実施対象になっているのかを調べる必要があります.
Bavotaらの研究[6] リファクタリングがコードスメルのあるクラスを対象に実施されるかを調査 3つのオープンソースソフトウェア(OSS)の開発履歴を用いて調査 リファクタリングとコードスメルの間に明確な関係は見られなかった リファクタリングがコードスメルのあるクラスに実施された割合は42% リファクタリングがコードスメルを除去した割合は7% 4:00 この問題に関する既存研究の1つとして, Bavotaらは, リファクタリングがコードスメルのあるクラスに実施されるかを調査していました. 彼らの調査対象は3つのOSSの複数のリリースバージョンのソースコードです. この調査の結果としては, リファクタリングがコードスメルのあるクラスに実施された割合は42%でした. ただし, リファクタリングでコードスメルが除去された割合がわずか7%であったので, 彼らはリファクタリングとコードスメルの間に明確な関係は見られなかったとしています. (リファクタリングされたクラス/全クラスは調査対象のシステムだと1~5%) [6] G. Bavota et al. An Experimental investigation on the Innate Relationship between Quality and Refactoring. Journal of Systems and Software, 2015.
既存研究の問題点 同種類のコードスメルの中での深刻度の違いについて考慮されていない リファクタリングの実施にはコストがかかるので, 全てのコードスメルを除去することは困難である 同種類のコードスメルでも, 深刻度の高いものが優先してリファクタリングされやすいと推測される コードスメルを完全に除去せず, 深刻度を和らげる程度にしかリファクタリングしない可能性もある 4:30 しかし, 彼らの研究では, 同種類のコードスメルの中で深刻度の違いについて考慮されていませんでした. リファクタリングの実施にはコストがかかるので, 全てのコードスメルを除去することは困難です. そのため, 深刻度の高いコードスメルが優先してリファクタリングされやすいと推測されます. また,コードスメルを完全に除去せず, 深刻度を和らげる程度にしかリファクタリングしない可能性もあります. そのため, コードスメルの深刻度について考慮して, 調査を行なう必要があります.
リファクタリングはコードスメルの深刻度を減少させるか? 調査概要 コードスメルの深刻度とリファクタリング実施の関係について, 3つのOSSの開発履歴を調査 リサーチクエスチョン(RQ) RQ1 RQ2 深刻度の高いコードスメルを含むクラス・メソッドがよりリファクタリングされるか? 5:00 本研究では, コードスメルの深刻度とリファクタリングの実施の関係について, 3つのOSSの開発履歴を調査しました. RQとして次の2つを設定しています. RQ1は「深刻度の高いコードスメルを含むクラス・メソッドがよりリファクタリングされるか?」で, RQ2は「リファクタリングはコードスメルの深刻度を減少させるか?」です. 次は調査対象のデータセットについて説明します. リファクタリングはコードスメルの深刻度を減少させるか?
調査対象のシステム 調査対象はJavaで書かれた3つのOSS Bavotaらの研究[6]と同じシステム 彼らが検出したリファクタリングの一覧も利用, 検出結果は目視で正解か確認されたので信頼できる 各システムの概要 システム データの収集期間 リリースの数 リリース毎の クラス数 リファクタリングの総数 Xerces-J 1999年11月~2010年11月 34 181~776 6052 ArgoUML 2002年10月~2011年12月 12 777~1,519 3423 Apache Ant 2000年1月~2010年12月 18 87~1,191 1493 5:27 Bavotaらの研究と同じデータセットとして, Javaで書かれた3つのOSSについて調査しました. 彼らが検出したリファクタリングの一覧も利用していますが, この検出結果は目視で正解か確認されたので信頼できると考えています. 下の表は各システムの概要を示しています. [6] G. Bavota et al. “An Experimental investigation on the Innate Relationship between Quality and Refactoring.” Journal of Systems and Software, 2015.
調査手順 1. コードスメルの検出 2. コードスメルの 深刻度の増減の計測 3. リファクタリングによる グループ分け 各リリースバージョンのソースコード 1. コードスメルの検出 inFusion コードスメルの深刻度 2. コードスメルの 深刻度の増減の計測 コードスメルの深刻度の増減 3. リファクタリングによる グループ分け リファクタリングの一覧 5:50 それでは調査手順を説明します. この図のように,手順は1から4に分けられます. まず手順1として, 調査対象のシステムの各リリースバージョンのソースコードから, コードスメルの検出を行ないました. リファクタリングされた コードスメルのあるクラス リファクタリングされなかった コードスメルのあるクラス 4. 2グループ間での有意差検定 RQ1: 深刻度の高さについて RQ2: 深刻度の増減について
コードスメルの検出 メトリクスの値の特徴に基づいてコードスメルを自動検出するツールInFusion*1を利用した コードスメルの深刻度を1~10の数値で評価する 深刻度1が最も軽微で, 深刻度10が最悪である 例)Blob Classの検出 inFusion 1. メトリクスを計測 2. 種類の判定 3. 深刻度の判定 LOC(行数) Blob Classの メトリクス値の特徴と一致すると判定 メトリクス値から 深刻度を判定 6:10 本研究ではソースコードからコードスメルを自動検出するツールinFusionを利用しました. このツールでは, ソースコードのメトリクス値の大きさなどから, コードスメルの示す問題の大きさを深刻度という, 1から10までの数値で表します. 深刻度1が最も軽微なコードスメルで, 深刻度10が最悪なコードスメルとします. 利用例として, inFusionでBlob Classを検出する例について説明します. ツールはメトリクス値を計測とコードスメルの種類の判定, 深刻度の判定の3つの手順でコードスメルを検出します. この例では, これらの行数や複雑度などのメトリクスから, Blob Classの特徴と一致すると判定され, 深刻度は4と判定されます. ツールの出力結果には,検出元のクラスやメソッドとコードスメルの種類, 深刻度の3つの情報が含まれます. WMC(複雑度) クラスA TCC(凝集度) 検出ツールの出力結果 クラス 種類 深刻度 クラスA Blob Class 4 *1http://www.intooitus.com/products/infusion
調査手順 1. コードスメルの検出 2. コードスメルの 深刻度の増減の計測 3. リファクタリングによる グループ分け 各リリースバージョンのソースコード 1. コードスメルの検出 inFusion コードスメルの深刻度 2. コードスメルの 深刻度の増減の計測 コードスメルの深刻度の増減 3. リファクタリングによる グループ分け リファクタリングの一覧 7:25 次に手順2として, 連続するリリースバージョン間で, コードスメルの深刻度を比較し, 深刻度の増減を計測しました. リファクタリングされた コードスメルのあるクラス リファクタリングされなかった コードスメルのあるクラス 4. 2グループ間での有意差検定 RQ1: 深刻度の高さについて RQ2: 深刻度の増減について
コードスメルの深刻度の増減の計測 連続するリリースバージョン間で各コードスメルの深刻度を比較し, 深刻度の増減を計測する リリース1のコードスメル リリース2のコードスメル クラスAのコードスメル クラスAのコードスメル クラスレベル クラスレベル 変化なし 種類 深刻度 Blob Class 4 種類 深刻度 Blob Class 4 この図はコードスメルの深刻度の増減の例を示しています. クラスAにはリリース1と2で共通する3つのコードスメルがあります. リリース1からリリース2の間で, Blob Classの深刻度は変化なしです. 2つのメソッドのBlob Operationの深刻度はそれぞれ増加と減少しています. コードスメルがなければ深刻度0とします. メソッドレベル メソッドレベル 増加 メソッド 種類 深刻度 m1() Blob Operation 5 m2() 1 メソッド 種類 深刻度 m1() Blob Operation 6 m2() - +1 減少 -1 コードスメルがなければ深刻度0とする
調査手順 1. コードスメルの検出 2. コードスメルの 深刻度の増減の計測 3. リファクタリングによる グループ分け 各リリースバージョンのソースコード 1. コードスメルの検出 inFusion コードスメルの深刻度 2. コードスメルの 深刻度の増減の計測 コードスメルの深刻度の増減 3. リファクタリングによる グループ分け リファクタリングの一覧 8:23 手順3では, リファクタリングが実施されたかどうかでコードスメルのグループ分けを行ないました. リファクタリングされた コードスメル リファクタリングされなかった コードスメル 4. 2グループ間での有意差検定 RQ1: 深刻度の高さについて RQ2: 深刻度の増減について
調査手順 1. コードスメルの検出 2. コードスメルの 深刻度の増減の計測 3. リファクタリングによる グループ分け 各リリースバージョンのソースコード 1. コードスメルの検出 inFusion コードスメルの深刻度 2. コードスメルの 深刻度の増減の計測 コードスメルの深刻度の増減 3. リファクタリングによる グループ分け リファクタリングの一覧 そして手順4では, リファクタリングされたコードスメルとリファクタリングされなかったコードスメルの2グループ間で, 2つのRQに答えるために有意差検定をそれぞれ行ないました. リファクタリングされた コードスメル リファクタリングされなかった コードスメル 4. 2グループ間での有意差検定 RQ1: 深刻度の高さについて RQ2: 深刻度の増減について
RQ1のための有意差検定 リファクタリングされたクラス・メソッドは, そうでないものに比べて, 深刻度が有意に高いかを調べた 深刻度の高いコードスメルを含むクラス・メソッドがよりリファクタリングされるか? RQ1: リファクタリングされたクラス・メソッドは, そうでないものに比べて, 深刻度が有意に高いかを調べた マン・ホイットニーのU検定という, ノンパラメトリックな有意差検定の一つを用いて片側検定を行なった リファクタリングされたBlob Class リファクタリングされなかったBlob Class 8:54 RQ1についての有意差検定では, リファクタリングが実施されたクラスは, リファクタリングされなかったクラスと比べて, コードスメルの深刻度が有意に高いかどうかを, ノンパラメトリックな有意差検定の一つである, マン・ホイットニーのU 検定を用いて調べました. 検定は各種類のコードスメルについて行ないます. 例えば, リファクタリングされたBlob ClassとリファクタリングされなかったBlob Classで, 深刻度の大きさの順位を比較します. リリース クラス 深刻度 1 クラスA 4 クラスD 10 2 リリース クラス 深刻度 1 クラスB 4 クラスC 2 8 同じ種類のコードスメル 深刻度の大きさの 順位を比較する … …
RQ1の回答 ○:有意差あり(p<0.05), 空欄:有意差なし, n/a:検定不可 表は検定結果から有意差があるかをまとめたものです. p値が0.05 以下で有意差があるとされるものを, ○印と黄色のハイライトで示しています. RQ1についてはBlob ClassとBlob operation, Sibiling Duplicationについて有意差が出ました。 (n/aはその種類のコードスメルのあるクラスに対してリファクタリングが実行されなかったことを表しています. 有意差の出たコードスメルの種類については, 深刻度が高いほどリファクタリングされやすい傾向にあります. ) ○:有意差あり(p<0.05), 空欄:有意差なし, n/a:検定不可
リファクタリングはコードスメルの深刻度を減少させるか? RQ2のための有意差検定 RQ2: リファクタリングはコードスメルの深刻度を減少させるか? リファクタリングされたクラス・メソッドは, そうでないものに比べて, 深刻度の増減が有意に低いか調べた RQ1と同様にマン・ホイットニーのU検定を用いた リファクタリングされたBlob Class リファクタリングされなかったBlob Class リリース クラス 深刻度の増減 1→2 クラスA クラスD -4 2→3 -2 リリース クラス 深刻度 の増減 1→2 クラスB 4 クラスC -1 2→3 1 10:17 次に, RQ2についての有意差検定では,リファクタリングされたクラス・メソッドは, そうでないものに比べて, 深刻度の増減が有意に低いかを, マンホイットニーのU検定で調べました. 例えば, リファクタリングされたBlob ClassとリファクタリングされなかったBlob Classで, 深刻度の増減の順位を比較します. 同じ種類のコードスメル 深刻度の増減の 順位を比較する … …
RQ2の回答 ○:有意差あり(p<0.05), 空欄:有意差なし, n/a:検定不可 こちらの表がRQ2の方での結果です. NAと表記している部分は, 検定を適用できなかった部分で, その種類のコードスメルについてはリファクタリング前後で深刻度が変化しなかったことを示しています. RQ2についてはBlob Class, Blob Operation, Internal Duplicationについて有意差が出ました。. (有意差の出たメソッドレベルのコードスメルでは, リファクタリングされたCode Smellの深刻度が減少する, またはリファクタリングされない場合と比べて増加の幅が小さい傾向にありました. ) ○:有意差あり(p<0.05), 空欄:有意差なし, n/a:検定不可
検定結果についての考察 RQ1とRQ2で共通して有意差があるコードスメルはBlob ClassとBlob Operation それぞれ深刻度の高いクラス・メソッドが優先してリファクタリングされ, 深刻度が減少する傾向にある 他の種類のコードスメルでは, 深刻度はリファクタリングの実施の指標として有用ではない 11:41 検定結果に対する考察です. RQ1とRQ2で共通して有意差が出た, Blob ClassとBlob Operationについては, 深刻度の高いクラス・メソッドが優先してリファクタリングされ, 深刻度が減少する傾向にありました. 他の種類のコードスメルでは, 深刻度はリファクタリングの実施の指標として有用ではありませんでした. 結論としては, Blob ClassとBlob Operationについては, 深刻度の高いコードスメルを優先的に提示することが有用であると考えられます. Blob ClassとBlob Operationについては, 深刻度の高いコードスメルを開発者に優先的に提示することが有用である
まとめと今後の課題 まとめ 今後の課題 コードスメルの深刻度とリファクタリングの関係について3つのOSSを調査した Blob ClassとBlob Operationについては, 深刻度が高いほどリファクタリングされやすい傾向があった 今後の課題 調査対象のシステムを増やす 12:30 最後にまとめです. 本研究では, コードスメルの深刻度とリファクタリングの関係について3つのOSSを調査しました. 調査の結果, Blob ClassとBlob Operationについて, 深刻度が高いほどリファクタリングされやすい傾向がありました. 今後の課題としては, 調査対象のシステムを増やすことが考えられます. 以上で発表を終わります. ご清聴ありがとうございました.