440 likes | 604 Views
オブジェクト指向メトリクスを用いた 開発支援法に関する研究. 神谷 年洋 2001/02/14. 背景(1). ソフトウェアの応用分野の拡大 ソフトウェアの大規模化・複雑化 開発期間の短縮・品質の向上 オブジェクト指向開発技術 開発/保守プロセス メトリクス. 背景(2). オブジェクト指向ソフトウェア開発 分析/設計/実装を通してオブジェクトを用いる オブジェクト指向プログラミング言語 Java や C++ など 開発ツール 大規模な再利用 フレームワーク オブジェクト指向メトリクス CK メトリクス. 背景(3).
E N D
オブジェクト指向メトリクスを用いた開発支援法に関する研究オブジェクト指向メトリクスを用いた開発支援法に関する研究 神谷 年洋 2001/02/14
背景(1) • ソフトウェアの応用分野の拡大 • ソフトウェアの大規模化・複雑化 • 開発期間の短縮・品質の向上 • オブジェクト指向開発技術 • 開発/保守プロセス • メトリクス
背景(2) オブジェクト指向ソフトウェア開発 • 分析/設計/実装を通してオブジェクトを用いる • オブジェクト指向プログラミング言語 • JavaやC++など • 開発ツール • 大規模な再利用 • フレームワーク • オブジェクト指向メトリクス • CKメトリクス
背景(3) オブジェクト指向ソフトウェアの品質評価/フォールト予測のために,オブジェクト指向メトリクスが用いられている ↓ オブジェクト指向複雑度メトリクスの適用において,オブジェクト指向開発技術や開発プロセスの特性が考慮されていない
目的 オブジェクト指向メトリクスを用いた開発支援法に関して研究を行った • 再利用技術 • 設計 • 開発プロセス • 重複コード
論文の構成 1. 緒論 2. 諸準備 3. 再利用を考慮した構造メトリクス計測法[1-2] →再利用部品と新規開発部品を区別することでフォールト予測精度を改善 4. フレームワークを用いたクラス分類に基づくフォールト予測手法[1-4] →フレームワークを利用したクラス分類によってフォールト予測精度を改善 5. CKメトリクスを開発プロセスの初期に計測する手法[1-6] →OMT法に基づく開発プロセスにチェックポイントを設け,各チェックポイントにおいて予測を行う 6. オブジェクト指向プログラミング言語向けのコードクローン検出手法[1-5] →オブジェクト指向プログラミング言語の文法知識を用いた,効果的な重複コード検出技術 7. むすび
フレームワークを用いたクラス分類法 [論文の4章] • 複雑度メトリクスによるフォールト予測 • CKメトリクス • 問題点 • フレームワークを利用したクラス分類法 • クラス分類を用いたフォールト予測 • 実験 • 結論と課題
複雑度メトリクスによるフォールト予測 (1)メトリクスを用いてプロダクトの複雑度を計測し (2)プロダクトに作りこまれるフォールトを予測する • 「複雑なプロダクトほどフォールトが作りこまれやすい」 • フォールトの予測はレビューやテストを効果的に配分するために用いられる
CKメトリクスおよびその他のメトリクス • CKメトリクス[Chidamber] DIT:クラス階層木内での深さ NOC:直接導出されている子子クラスの数 RFC:呼び出すメソッドの種類数(RFCR, RFCN) CBO:結合するクラスの種類数(CBOR, CBON) WMC:クラスのメソッド数 LCOM:メソッドの凝集度の欠如の度合い • その他のメトリクス NIV:インスタンス変数の数 SLOC:ソースコードの行数 継承 結合 クラスの 内部複雑度 [Chidamber] S.R. Chidamber and C.F. Kemerer: “A Metrics Suite for Object Oriented Design”, IEEE Trans. on Software Eng., vol., 20, No. 6, Jun 1994.
問題点 • クラスの機能によりメトリクス値の分布が異なる[Basili] • 一般的なソースコードにおいて,クラスの機能分類を自動的に行うことは難しい [Basili] V. R. Basili, L. C. Briand, W. L. Mélo: “A validation of object-oriented design metrics as quality indicators,” IEEE Trans. on Software Eng., Vol. 20, No. 22, pp. 751-761 (1996).
フレームワークを利用したクラス分類法 • フレームワークのクラスから,「導出が期待される」クラスを選出する →代表クラス • どの代表クラスから導出されているかによって,新規開発クラスを分類する フレームワーク ( 代表クラス ) 新規開発クラス
クラス分類を用いたフォールト予測 (1)代表クラスを選出する (2)基準となるデータを収集する メトリクスを計測するためのプロダクト(たとえばソースコード)から,クラスごとに,分類,メトリクス値,フォールト修正時間を記録する (3)予測式の作成 重回帰分析によって,クラス分類ごとに,メトリクスを入力とし,フォールト修正時間を出力とする予測式を作成する (4)フォールト修正時間を予測する フォールト修正時間の予測を行いたいクラスから計測したメトリクスを,分類に応じた予測式に当てはめる
実験概要 • ある企業の新人研修におけるプログラム開発演習 • GUIを備えた電子メールの配送システム • 4から5人のチームによる開発であり,各開発者はサブシステムを開発する • インストラクタによって受け入れテストが実施される • Visual C++,フレームワークとしてMFC(Microsoft Foundation Class)を用いる • 開発規模はチームあたり3千行程度(再利用分を含まない) • 最終的には,17人分,124個のクラスのデータが利用できた
クラス分類 (1)CDocument:アプリケーションのデータを格納 (2)CView:ユーザーに対してデータを表示 (3)CDialog: ユーザーからデータを受け取る エラーメッセージ出力する (4)CWinApp:アプリケーションの設定に関する処理 (5)CFrameWnd:アプリケーションのウィンドウの管理 (6)CSocket:通信を行う「ソケット」を実装 (7)その他:上記のいずれにも属さないクラス
収集されたメトリクス値の分布(1/2) CDocument CDialog CView CWinApp CFrameWnd CSocket
収集されたメトリクス値の分布(2/2) • メトリクス値の傾向は,CDocument, CView, CWinApp, CFrameWndで大きく異なる • それぞれの分類内では似た傾向にある →クラス分類が適切であったことがわかる その他
フォールト予測精度の比較 クラス分類を用いない場合 クラス分類を用いた場合 相関係数で比較すると0.53(分類を用いない), 0.74(分類を用いる)となる
考察 • クラス分類を行うことによってフォールト予測精度が向上する • 統計的には,「クラス分類」というあらたな名義尺度のメトリクスを,ダミー変数として用いることを意味する • クラス分類を行う・・・「クラス分類」メトリクスを予測式に取り入れる • クラス分類を行わない・・・「クラス分類」以外のメトリクスだけで予測式を立てる • 従って,クラス分類間でメトリクス分布に差があれば,分類によって予測精度が向上する
結論と課題 結論 • フレームワークを用いたクラス分類法を提案 • 評価実験では,CKメトリクスによるフォールト予測精度が向上した 課題 • クラス分類の精密化 • 代表クラス選出の自動化 • 適用事例の追加
オブジェクト指向プログラミング言語向けのコードクローン検出手法オブジェクト指向プログラミング言語向けのコードクローン検出手法 [論文の6章] • コードクローン • 既存のクローン検出手法 • 問題点 • 提案するクローン検出手法 • 適用実験 • 結論と課題
コードクローンとは • ソースコード中に類似したコード片があるとき,それらをコードクローンという
コードクローンが起こす問題 • コードクローンはソフトウェア保守を困難にする • クローンにフォールトが含まれる場合,すべてのクローンについて修正を行わなければならない • 機能追加も同様 • 設計書には表れないソースコードの潜在的欠陥 • 大規模なソースコードからクローンを人手で発見するのは非現実的である
既存のクローン検出手法(ツール) Dup[Baker] • 行単位でソースコードを比較してクローンを検出する →基本的に入力ソースファイルの記述言語を問わない Baxterらのツール[Baxter] • C言語のソースファイルを入力,構文解析して,解析木(の部分木)を比較する [Baker] B. S. Baker: “On finding Duplication and Near-Duplication in Large Software System,” Proc. of The Second IEEE Working Conf. on Reverse Eng., pp. 86-95, Tronto, Canada (Jul., 1995). [Baxter] I. D. Baxter, A. Yahin, L. Moura, M. Sant’Anna, and L. Bier: “Clone Detection Using Abstract Syntax Trees,” Proc. of ICSM ’98, pp. 368-377, Bethesda, Maryland (Nov., 1998).
問題点 • オブジェクト指向プログラミング言語への対応 • オブジェクト指向プログラミング言語では,クラスのスコープルール,名前空間,汎用型などにより,構造をもった名前が用いられる std::map<int, std::string> • クローンを選択する手法 • テーブルの初期化など,検出しても意味がないクローンがある
提案するクローン検出手法 ソースコードを字句解析してトークンの列に直してから処理する • 文法知識に基づいたコード変形 • クラススコープや名前空間による複雑な名前の正規化を行う • 初期化テーブルを取り除く • モジュールの区切りを認識する • 言語依存部分を取り替えることで,さまざまなプログラミング言語に対応
クローン検出手順 (1)ソースコードを入力し,トークンの列にする (2)変形ルールにより,トークン列を変形する (3)パラメータ置換を行う (4)マッチングアルゴリズムによりクローンを検出する (5)クローンの位置(ファイル,行)を出力する
ステップ(1):ソースコードを入力し,トークンの列にするステップ(1):ソースコードを入力し,トークンの列にする 1. static void foo() throws RESyntaxException { 2. String a[] = new String [] { "123,400", "abc", "orange 100" }; 3. org.apache.regexp.RE pat = new org.apache.regexp.RE("[0-9,]+"); 4. int sum = 0; 5. for (int i = 0; i < a.length; ++i) 6. if (pat.match(a[i])) 7. sum += Sample.parseNumber(pat.getParen(0)); 8. System.out.println("sum = " + sum); 9. } 10. static void goo(String [] a) throws RESyntaxException { 11. RE exp = new RE("[0-9,]+"); 12. int sum = 0; 13. for (int i = 0; i < a.length; ++i) 14. if (exp.match(a[i])) 15. sum += parseNumber(exp.getParen(0)); 16. System.out.println("sum = " + sum); 17. }
ステップ(2):変形ルールにより,トークン列を変形するステップ(2):変形ルールにより,トークン列を変形する
ステップ(3):パラメータ置換を行う (変数,関数,型の識別子を,単一の「パラメータ」トークンに置き換える)
ステップ(4): マッチングアルゴリズムにより,クローンを検出
ステップ(5):クローンの位置を出力する 1. static void foo() throws RESyntaxException { 2. String a[] = new String [] { "123,400", "abc", "orange 100" }; 3. org.apache.regexp.RE pat = new org.apache.regexp.RE("[0-9,]+"); 4. int sum = 0; 5. for (int i = 0; i < a.length; ++i) 6. if (pat.match(a[i])) 7. sum += Sample.parseNumber(pat.getParen(0)); 8. System.out.println("sum = " + sum); 9. } 10. static void goo(String [] a) throws RESyntaxException { 11. RE exp = new RE("[0-9,]+"); 12. int sum = 0; 13. for (int i = 0; i < a.length; ++i) 14. if (exp.match(a[i])) 15. sum += parseNumber(exp.getParen(0)); 16. System.out.println("sum = " + sum); 17. }
変形ルールを用いない場合 1. static void foo() throws RESyntaxException { 2. String a[] = new String [] { "123,400", "abc", "orange 100" }; 3. org.apache.regexp.RE pat = new org.apache.regexp.RE("[0-9,]+"); 4. int sum = 0; 5. for (int i = 0; i < a.length; ++i) { 6. if (pat.match(a[i])) 7. sum += Sample.parseNumber(pat.getParen(0)); 8. } 9. System.out.println("sum = " + sum); 10. } 11. static void goo(String [] a) throws RESyntaxException { 12. RE exp = new RE("[0-9,]+"); 13. int sum = 0; 14. for (int i = 0; i < a.length; ++i) { 15. if (exp.match(a[i])) 16. sum += parseNumber(exp.getParen(0)); 17. } 18. System.out.println("sum = " + sum); 19. } 4-6行目と 13-15行目, 8-10行目と 17-19行目
Java向けの変形ルール RJ1:パッケージ名除去 ( PackageName ‘.’ )+ ClassName → ClassName RJ2:Callee挿入 NDotOrNew NClassName ‘(‘ → NDotOrNew CalleeIdentifier ‘.’ NClassName ‘(‘ RJ3:テーブル初期化除去 '=' '{' InitalizationList, '}' → '=' '{' UniqueIdentifier '}‘ ']' '{' InitalizationList, '}' → ']' '{' UniqueIdentifier '}' RJ4:モジュールの分離 トップレベルの定義や宣言の終わりにUniqueIdentifier を挿入する
最適化 • Suffix-treeによるO(n log n)のマッチングアルゴリズム (入力ソースファイルの大きさをnとして) • 簡便なアルゴリズム(最適アルゴリズムはO(n)) • メモリ使用量を削減 • 「文の最初のトークンだけがクローンの開始位置となることができる」制約によりメモリ使用量を削減 • 大規模なソースファイルには分割して処理を行う
JDKのライブラリへの適用 • JDK(Java Development Kit) 1.2.2(サンプルとデモプログラムを除く) • 入力ファイルは1648個,約50万行 • ツールの実行には,Pentium III 650MHzおよび1GBのRAMを持つPCで約3分を要した
クローンの散布図 • 両軸はソースファイルを辞書順に並べたもの • 20行以上のクローンを図示 • 多くのクローンが密集している(A) • 最長のクローン(B) B A
クローンが密集している部分(A) • src/javax/swing/plaf/multi/*.javaの29のファイル • コード生成ツールによって生成された • いくつかはクラス名を除いてまったく同じクラスの定義を含んでいた 31| */ 32| public class MultiButtonUI extends ButtonUI { 33| 160| public static ComponentUI createUI(JComponent a) { 161| ComponentUI mui = new MultiButtonUI(); 162| return MultiLookAndFeel.createUIs(mui, 163| ((MultiButtonUI) mui).uis, 164| a); 165| }
最長のクローン(B) • 最長のクローン(349行) • src/java/util/Arrays.javaの18の“sort”メソッド • シグネチャ(引数の型と数)が異なる • アルゴリズムは同一
変形ルールの評価 • 変形/置換なしでは発見されるクローンは半減する
その他の適用実験 オープンソース • Qt(C++,24万行) • C++向けの変形ルールの効果を確認した • LinuxとFreeBSDのカーネルとドライバ(C,160万行+130万行) • ドライバ部分にクローン「ファイル」が多数存在する • システム間で名前が異なるファイル 商用 • NTTデータ (出入国管理システム) • COBOL,120万行 • NASDA(ロケットの制御・管制) • C,50万行
結論と課題 • 結論 • ソースコードの変形を用いるコードクローン検出手法を提案した • 実験では,提案する手法がJDKのライブラリから効果的にコードクローンを検出することが確認された • 課題 • 構文によるクローン選別 • クローン除去 • クローン検出の保守プロセスでの利用 「横並びリスト」を補完する手段
むすび • 複雑度メトリクスによるフォールト予測 • 再利用を考慮した構造メトリクス計測法 • CKメトリクスを開発プロセスの初期に計測する手法 • フレームワークを用いた開発においてクラス分類を行い予測精度を高める手法 →フレームワークによってクラス分類を行う手法を提案し,実験によってフォールト修正時間予測精度を評価 • コードクローン検出 • オブジェクト指向プログラミング言語向けのコードクローン検出手法 →検出手法を提案し,JDKのソースファイルに適用した
Suffix-tree 以下の条件を満たす木 (1)木の葉は部分文字列の開始位置 (2)根から葉までラベルをたどると部分文字列になる (3)ひとつの節点から出る辺のラベルはすべて異なる文字で始まる →共通のパス=クローン (Suffix-treeをO(n)で構築するアルゴリズムが知られている)