ソースコードに対して 適用可能な編集手順を探索する リファクタリング支援手法の提案 譜久島亮,吉田則裕,松下誠,井上克郎 大阪大学 大学院情報科学研究科 SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 1 発表の概要 リファクタリングとは メンバの移動 リファクタリング支援機能の問題点 編集手順を探索するリファクタリング支援手法 探索の例 提案手法の処理概要 ケーススタディ まとめと今後の課題 SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 2 リファクタリング リファクタリングの定義 外部から見たプログラムの振る舞いを変えずにプログラムの 内部の構造を改善する作業[1] リファクタリングの目的 欠陥の発見を容易にする プログラムの可読性を上げる 機能追加をしやすくする 典型的なリファクタリングがまとめられている[1] メソッドの抽出 フィールドの移動 メソッドの移動 開発者が頻繁に行う リファクタリング[2] [1] M. Fowler : Refactoring: improving the design of existing code, Addison Wesley (1999). [2] G. C. Murphy, M. Kersten and L. Findlater: “How Are Java Software Developers Using the Eclipse IDE?’’, IEEE Softw.,23, 4, pp. 76-83(2006) SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 3 メンバ(フィールド,メソッド)の移動 動機 適切なクラスにメンバを移動し クラスの機能を明確にする 他のリファクタリングにも利用 クラスの抽出 クラスのインライン化 処理内容がClassAに に不適切なメソッド ClassA{ …. method( ){ …. } } 移動されたメソッド ClassB{ method( ){ } …. } } SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 4 メンバの移動に必要な検討の目的 移動するメンバと関連があるメンバの移動 関連があるメンバも移動しクラスの機能をより明確にする 移動先クラスと移動元クラス間の参照方法の変更の検討 メンバの移動後もメンバ間で参照関係を保つことで振る舞い を保存する 移動先クラス 移動元クラス class Rental{ public void print(Customer c); 関連するメンバ public int public void print( ); count(Customer c); 移動するメンバ public int count( ); } ・・・ 内部 } 内部 内部 内部 ・・・ ・・・ ・・・ c.mList[i]. mList.length( ); mList[i].getName( ); c.mList.length( ); getName( ); class Customer{ public List mList ; ・・・ ・・・ ・・・ ・・・ SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 5 メンバの移動により参照切れが起こる場合 privateメンバの移動 privateメンバを参照しているメンバの移動 プログラムの振る舞いの保存のために 参照切れを解消するメンバの移動や参照方法の検討が必要である 被参照メンバ class A{ private Type memberA ; memberB; } class B{ 参照メンバ } (a) メンバの移動前 ソースコード class A{ private Type memberA ; } class B{ memberB; } class A{ memberB; } class B{ private Type memberA ; } (b) memberBをBへ移動 (c) memberAをBへ移動 したソースコード したソースコード SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 6 参照切れを解決する編集例(1/2) class Customer { private List mList; Rental rental; public void print( ); public int count( ); } 移動 class Rental { 移動 } class Rental { }public int count(Customer c); } class Customer { 被参照メンバの カプセル化 Rental rental; private List mList; public void print( ); public List getMovie( ); public void setMovie(List m); } class Rental { public int count(Customer c); } (a) メンバの移動後の 参照切れを含むソースコード (b) 被参照メンバの カプセル化を行ったソースコード SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 7 参照切れを解決する編集例(2/2) class Customer { private List mList; Rental rental; public void print( ); 移動 } class Rental { public int count(Customer c); } (a) メンバの移動後の 参照切れを含むソースコード class Customer { Rental rental; フィールドの移動 } メソッドの移動 class Rental { private List mList; public void print( ); public int count( ); } (b) メンバの移動を 行ったソースコード ソースコードや開発者の意図より編集手順が複数存在する SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 8 リファクタリング支援機能 統合開発環境Eclipseではリファクタリング支援機能が 提供されている メソッドの移動 → 選択されたメソッドの他クラスへの移 動を支援 親クラスの抽出 → 選択されたソースコードの親クラス の作成を支援 既存のリファクタリング支援機能にはリファクタリングに伴なう 複数の編集手順を提示できるものが確認できない 目的のソースコードを得るための編集手順が選択が困難である 編集の適用や取消を繰り返すことにより編集作業に時間がかかる SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 9 参照切れが発生するメンバの移動例 ソースコードの遷移 Eclipseでのメンバの移動の例 カプセル化 元に戻す class Customer { 移動 private List mList ; Rental rental; public void setMovie(List 移動 m) { int count( ){ public …mList = m; } mList.length( ); }public List getMovie() { return mList; } public void print( ) { public … void print( ){ …getMovie( ).getName( mList[i].getName( ); ); ); rental.mList[i].getName( }} } class Rental { private List mList; public int count(Customer count( ){ c){ …. c.getMovie mList.length( c.mList.length( ); ); } .length( ); }} メソッドを 移動 元に 戻す カプセル化 フィールド を移動 問題点 手戻りにより作業時間がかかる 目的とするソースコードが得にくい SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 10 研究の目的について リファクタリングを行う際に 適用可能な編集手順を探索する リファクタリング完了までの編集手順 編集手順を適用したソースコード 編集の取り消しを防ぎ、作業時間が短縮 SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 11 提案手法 適用可能な編集手順の探索結果の例 「メソッドの移動」リファクタリングの編集手順探索の例 Customer. countを Rentalへ移動 Customer.mList の修飾子を publicに変更 Rental.mList の修飾子を publicに変更 Customer.mList をRentalへ移動 Customer.mList のカプセル化 Customer.print をBへ移動 Rental.mList のカプセル化 コンパイル可能なソースコード コンパイルエラーを含むソースコード SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 12 適用可能な編集ステップ 参照切れコンパイルエラーを解決する編集ステップ 修飾子の変更 メンバの移動 被参照メンバの修飾子 移動先クラスへメンバを を変更する 移動する private Type value ; public Type value ; class A{ private Type value ; … }; class B{ フィールドのカプセル化 フィールドが所属するクラ スにgetterメソッドとsetter メソッドを作成する class A{ private Type value ; public void set(Type t) { this.value = t; } public Type get( ) { return value; } }; } コンパイルエラーが存在するソースコードに適用 SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 13 提案手法の処理概要 1. 編集ステップ導出のために以下の情報を取得 移動元クラスと移動先クラス 被参照メンバとその所属クラス 参照メンバとその所属クラス 2. 参照切れを解決する編集ステップを導出 被参照メンバの修飾子の変更 移動先クラスへのメンバの移動 被参照メンバのカプセル化 3. 参照切れを含むソースコードに各編集ステップを適用 4. 編集ステップを適用したソースコードで参照切れを含む ソースコードについて1~3の処理を行う 5. ソースコードと適用した編集ステップを木構造で構築 SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 14 編集ステップ導出のための情報取得 適用したメンバの移動より情報を取得 移動元クラス 移動先クラス 被参照メンバ class A{ private Type memberA ; memberB; } class B{ 参照切れより情報を取得 被参照メンバとその所属クラス 参照メンバとその所属クラス 参照メンバ メンバの移動 } 移動元クラス 移動元クラス A 移動先クラス B 被参照メンバ memberA 被参照メンバの所属クラス A 参照メンバ memberB 参照メンバの所属クラス B class A{ private Type memberA ; } 移動先クラス class B{ memberB; } A.memberAは不可視 SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 15 提案手法の処理概要 1. 編集ステップ導出のために以下の情報を取得 移動元クラスと移動先クラス 被参照メンバとその所属クラス 参照メンバとその所属クラス 2. 参照切れを解決する編集ステップを導出 被参照メンバの修飾子の変更 移動先クラスへのメンバの移動 被参照メンバのカプセル化 3. 参照切れを含むソースコードに各編集ステップを適用 4. 編集ステップを適用したソースコードで参照切れを含む ソースコードについて1~3の処理を行う 5. ソースコードと適用した編集ステップを木構造で構築 SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 16 編集ステップの導出(1/3) 被参照メンバの修飾子の変更 被参照メンバ 移動元クラス A 移動先クラス B 被参照メンバ memberA 被参照メンバの所属クラス A 参照メンバ memberB 参照メンバの所属クラス B 編集ステップ class A{ private Type memberA ; } class B{ memberB; } class A{ public Type memberA ; } class B{ memberB; } memberAの修飾子をpublicに変更 SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 17 編集ステップの導出(2/3) 移動元クラスから移動先クラスへメンバの移動 移動元クラス 移動元クラス A 移動先クラス B 被参照メンバ memberA 被参照メンバの所属クラス A 参照メンバ memberB 参照メンバの所属クラス B class A{ private Type memberA ; } class B{ 移動先クラス memberB; } class A{ } class B{ private Type memberA ; memberB; } 編集ステップ 移動元クラスであるAに所属している memberAを移動先クラスであるBへ移動 SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 18 編集ステップの導出(3/3) 被参照メンバのカプセル化 (被参照メンバがフィールドの場合) 被参照メンバ memberA 被参照メンバの所属クラス A 参照メンバ memberB 参照メンバの所属クラス B 移動元クラス A 移動先クラス B 編集ステップ memberAのgetter,setterを Aに追加 被参照メンバ class A{ private Type memberA ; } class B{ memberB; } class A{ private Type memberA ; public void set(Type type){ memberA = type; } public Type get( ){ return memberA; } } class B{ memberB; } SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 19 提案手法の処理概要 1. 編集ステップ導出のために以下の情報を取得 移動元クラスと移動先クラス 被参照メンバとその所属クラス 参照メンバとその所属クラス 2. 参照切れを解決する編集ステップを導出 被参照メンバの修飾子の変更 移動先クラスへのメンバの移動 被参照メンバのカプセル化 3. 参照切れを含むソースコードに各編集ステップを適用 4. 編集ステップを適用したソースコードの参照切れが解決さ れるまで1~3の処理を行う 5. ソースコードと適用した編集ステップを木構造で構築 SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 20 編集ステップの適用と繰り返し処理 メンバの移動 ソースコード 情報の抽出 取得 参照切れを含 むソースコード 編集ステップ の適用 参照切れの情報 適用済 編集ステップ 導出 履歴の取得 編集ステップを適 用したソースコード 適用可能な 編集ステップ 履歴の保持 編集ステップ ソースコード 構築 編集ステップを有効辺 ソースコードを頂点とする木 SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 21 ケーススタディの概要 右の例に対して提案手法を適用 Customer.count,Customer.print はprivateフィールド Customer.mListを参照 Customer.countをRentalへ移動す る 被参照メンバ Customer.mList 被参照メンバの所属クラス Customer 参照メンバ Rental.count 参照メンバの所属クラス Rental 移動元クラス Customer 移動先クラス Rental class Customer { class Customer { private List mList ; private List mList ; public void print( ) { public int count( ){ … … mList[i].getName( ); mList.length( ); … … } } } public void print( ) { class Rental{ … public int mList[i].getName( ); count(Customer C){ … … } メソッドの移動 c.mList.length( ); } … class Rental{ } } } SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 22 編集ステップの導出(修飾子の変更) 被参照メンバ Customer.mList 編集ステップ Customer.mListの修飾子をpublicに変更 Customer.mList の修飾子を publicに変更 Customer. countを Rentalへ移動 class Customer { privateList public ListmList mList;; public void print( ) { … mList[i].getName( ); … } } class Rental{ public int count(Customer C){ … c.mList.length( ); … } } 編集手順とソースコードを保持 SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 23 編集ステップの導出(メンバの移動) 被参照メンバ Customer.mList 被参照メンバの所属クラス Customer 移動元クラス Customer 移動先クラス Rental 編集ステップ Customer.mListをRentalへ移動 Customer. countを Rentalへ移動 Customer.mList の修飾子を publicに変更 Customer.mList をRentalへ移動 編集手順とソースコードを保持 class Customer { class Customer { private List mList ; private List mList ; public void print( ) { public void print( ) { … … mList[i].getName( ); mList[i].getName( ); … … } } } } class Rental{ class Rental{ private List mList ; public int public int count(Customer c){ count(Customer c){ … … c.mList.length( ); c.mList.length( ); … … } } } } SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 24 編集ステップの導出(カプセル化) 被参照メンバ Customer.mList 被参照メンバの所属クラス Customer 編集ステップ Customer.mListのgetter,setterを追加 Customer.mList の修飾子を Customer. publicに変更 countを Customer.mList Rentalへ移動 をRentalへ移動 Customer.mList のカプセル化 編集手順とソースコードを保持 class Customer { class List Customer private mList ;{ private mList ; public voidList setMovie(List m){ public mList void = m; print( ) { … } mList[i].getName( public List getMovie( ){ ); … mList; return } } } public void print( ) { class Rental{).getName( ); …getMovie( …}public int count(Customer c){ } class … Rental{ c.mList.length( ); public int … count(Customer c){ } …c.getMovie( ).length( ); } } … } SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 25 編集ステップ導出・適用の繰り返し処理 編集ステップを適用したソースコードで参照切れコンパイルエ ラーを含むソースコードについて繰り返し編集ステップの導出・ 適用を繰り返す Customer. countを Rentalへ移動 Customer.mList の修飾子を publicに変更 Rental.mList の修飾子を publicに変更 Customer.mList をRentalへ移動 Customer.mList のカプセル化 Customer.print をBへ移動 Rental.mList のカプセル化 ソースコードから以下を得ることができた Customer.countを移動した際の適用可能な編集手順 コンパイル可能なソースコード SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 26 ケーススタディの考察 適用可能な編集手順とコンパイル可能なソースコードを 得ることができた 開発者が参照切れを解決する編集作業を行わなくてす むので有用と言える 開発者が複数のソースコードから目的のソースコードを 選択するためのユーザーインターフェースが必要である 提案手法で探索した編集手順は「メンバの移動」リファ クタリングの編集手順の部分的な編集手順である 参照切れを解決する編集手順のみを探索している SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 27 まとめと今後の課題 まとめ 参照切れが発生するメンバの移動に伴なう適用可能な編集 手順の探索を行った • 適用可能な編集手順とコンパイル可能なソースコードを得るこ とができた 今後の課題 開発者にコンパイル可能な複数のソースコードの差異を示し、 目的のソースコードの選択を支援するようなインターフェース が必要 探索できる編集手順を増やす • 移動するメンバと参照関係のあるpublicメンバの移動など 提案手法の評価 • 提案手法を用いた場合と用いなかった場合のリファクタリング 作業時間の測定 SIGSS Software Engineering Laboratory, Department of Computer Science, Graduate School of Information Science and Technology, Osaka University 28
© Copyright 2024 ExpyDoc