コードクローン検出に基づくデザイン パターン適用支援手法の提案と実現

Slides:



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

背景 ソフトウェアの大規模化・複雑化 生産性と品質の向上 ↓ オブジェクト指向分析設計の適用 開発ツールの投入.
XHTML構文検証手法における スクリプト要素の静的解析アルゴリズム
同時変更が生じたTemplate Method パターンの適用事例の調査
デザインパターンの適用事例に対するプログラムの安定性の調査
プログラムの変更前後での 実行履歴の差分検出手法
Myoungkyu Song and Eli Tilevich 発表者: 石尾 隆(大阪大学)
情報伝播によるオブジェクト指向プログラム理解支援の提案
剽窃 他人の作品や論文を盗んで,自分のものとして発表すること. プログラムが剽窃される事例もある. Aさんのプログラム Xさんのプログラム
リファクタリングのための 変更波及解析を利用した テスト支援ツールの提案
メソッド名とその周辺の識別子の 相関ルールに基づくメソッド名変更支援手法
CKメトリクスを用いてリファクタリングの 効果を予測する手法の提案
プログラム実行履歴を用いたトランザクションファンクション抽出手法
プログラム実行時情報を用いたトランザクションファンクション抽出手法
ソースコードの変更履歴における メトリクス値の変化を用いた ソフトウェアの特性分析
ソフトウェア工学 知能情報学部 新田直也.
ギャップを含むコードクローンの フィルタリング手法の提案
コードクローンに含まれるメソッド呼び出しの 変更度合の分析
コードクローンに含まれるメソッド呼び出しの 変更度合の調査
識別子の命名支援を目的とした動詞-目的語関係の辞書構築
ソードコードの編集に基づいた コードクローンの分類とその分析システム
コードクローンの分類に基づいた メソッド引き上げ手順の提案とその有効性評価
ポインタ解析におけるライブラリの スタブコードへの置換の効果
シーケンス図を用いて実行履歴を可視化するデバッグ環境の試作
利用関係に基づく類似度を用いたJavaコンポーネント分類ツールの作成
クローンセットに対する主要編集者の分析法の提案と調査
11 ソフトウェア工学 Software Engineering デザインパターン DESIGN PATTERNS.
Javaプログラムの変更を支援する 影響波及解析システム
社会シミュレーションのための モデル作成環境
コードクローン検出ツールを用いた ソースコード分析システムの試作と プログラミング演習への適用
リファクタリング支援のための コードクローンに含まれる識別子の対応関係分析
プログラム動作理解支援を目的とした オブジェクトの振舞いの同値分割手法
ソースコードの特徴量を用いた機械学習による メソッド抽出リファクタリング推薦手法
コードクローンの動作を比較するためのコードクローン周辺コードの解析
コードクローンに対する一貫性のない変更に起因する欠陥の検出
柔軟に変更可能な字句解析機構を持つ コードクローン検出ツールの開発
UMLモデルを対象とした リファクタリング候補検出の試み
プログラム実行履歴を用いたコードクローン検出手法
バイトコードを単位とするJavaスライスシステムの試作
コードスメルの深刻度がリファクタリングの実施に与える影響の実証的研究
コード片に共通した特性を自動抽出する ソースコード閲覧ツールの試作
○ 後藤 祥1,吉田 則裕2 ,井岡 正和1 ,井上 克郎1 1大阪大学 2奈良先端科学技術大学院大学
ソフトウェア保守のための コードクローン情報検索ツール
コードクローンの理解支援を目的としたコードクローン周辺コードの解析
コードクローン分類の詳細化に基づく 集約パターンの提案と評価
コーディングパターンの あいまい検索の提案と実装
コードクローン間の依存関係に基づく リファクタリング支援環境の実装
オブジェクトの協調動作を用いた オブジェクト指向プログラム実行履歴分割手法
ソフトウェア工学 知能情報学部 新田直也.
プログラムスライスを用いた凝集度メトリクスに基づく 類似メソッド集約候補の順位付け手法
設計情報の再利用を目的とした UML図の自動推薦ツール
コードクローン間の依存関係に基づく リファクタリング支援手法の提案と実現
クローン検出ツールを用いた ソフトウェアシステムの類似度調査
オープンソースソフトウェアに対する コーディングパターン分析の適用
メソッドの同時更新履歴を用いたクラスの機能別分類法
コードクローン間の依存関係に基づく リファクタリング支援手法の提案と実現
UMLモデルを対象とした リファクタリング候補検出手法の提案と実現
ロールを基にした構造進化の表現 Role based Evolution Dependency Structure Matrix
欠陥検出を目的とした類似コード検索法 吉田則裕,石尾隆,松下誠,井上克郎 大阪大学 大学院情報科学研究科
ソフトウェア理解支援を目的とした 辞書の作成法
エイリアス関係を考慮した Javaプログラム用静的スライシングツール
コードクローン解析に基づく デザインパターン適用候補の検出手法
メソッド抽出リファクタリングが 行われるメソッドの特徴調査
木構造の比較に基づく メソッド呼び出し履歴の変化の可視化手法
オブジェクト指向言語における セキュリティ解析アルゴリズムの提案と実現
識別子の読解を目的とした名詞辞書の作成方法の一試案
オブジェクト指向メトリクスを用いた 開発支援に関する研究 --- VC++とMFCを用いた開発を対象として ---
プログラム理解のための 付加注釈 DocumentTag の提案
プログラム依存グラフを用いた ソースコードのパターン違反検出法
Presentation transcript:

コードクローン検出に基づくデザイン パターン適用支援手法の提案と実現 大阪大学 吉田昌友,吉田則裕,井上克郎 コードクローン解析に基づくデザインパターン適用候補の検出手法について, 井上研究室,吉田が発表します. 2008/03/13 情報処理学会第70回全国大会

概要 デザインパターンの適用を支援する手法の提案 Factory Methodパターンの適用候補を検出する手法の提案と実現 オープンソースソフトウェアを対象とした適用実験 本研究の概要を述べます. 本研究では,デザインパターンの1つであるファクトリーメソッドパターンの適用候補を ソースコードから検出する手法を提案します. 対象となるソフトウェアに含まれるコードクローンを解析することで ファクトリーメソッドパターンの適用候補を検出します. そして,提案手法を実装したツールを試作し, オープンソースソフトウェアを対象に適用実験を行いました.

デザインパターン ソフトウェアの設計において頻繁に発生する問題に対する洗練された解決策[1] デザインパターン記述の構成要素[1] パターン名 デザインパターンを識別するための名前 問題 デザインパターンを適用すべきコンテキスト 解法 設計の要素の役割や関連についての記述 結果 デザインパターンを使用する場合の結果やトレードオフ はじめに,デザインパターンについて説明します. デザインパターンとは,ソフトウェアの設計において頻繁に発生する問題に対する, 洗練された解決策を言います. 実際のソフトウェア開発では,デザインパターンを利用することで設計が改善する部分に デザインパターンが利用されていないことがあります. そこで,既存のソフトウェアに対してデザインパターンを適用することで 設計を改善する方法が提案されています. [1] E. Gamma, et al., Design Patterns: Elements of Reusable Object-Oriented Software, Addition Wesley, 1995.

Factory Methodパターン 少ない修正で子クラスを追加可能 同じインタフェースで異なる処理をするオブジェクト コンストラクタの呼び出し文が異なり拡張しにくい Factory Method Creator Product 生成 createProduct : Product 少ない修正で子クラスを追加可能 ConcreteCreator1 ConcreteCreator2 ConcreteProduct1 ConcreteProduct2 createProduct : Product createProduct : Product 本研究ではファクトリーメソッドパターンに注目しました. ファクトリーメソッドパターンでは,プロダクトクラスのオブジェクトを クリエイタークラスが生成して使う構造になっています. オブジェクトの生成には,コンストラクタを直接使わず, クリエイトプロダクトメソッドを使って間接的に生成します. クリエイタークラスではプロダクトクラスのオブジェクトを生成するクリエイトプロダクトメソッドの インタフェースしか定義されていませんので, 実際にはクリエイタークラスの子クラスであるコンクリートクリエイターワンクラスが クリエイトプロダクトメソッドをオーバーライドしてプロダクトクラスの子クラスの オブジェクトを生成する処理を行います. この例では,クリエイトプロダクトメソッドがファクトリーメソッドと呼ばれます. ファクトリーメソッドパターンを使う利点は,例えば,プロダクトクラスに 新たに子クラスが追加され, 同様の処理をクリエイタークラスの新たな子クラスで行うように変更があっても, クリエイトプロダクトメソッドを新たにオーバーライドするだけで, プロダクトクラスの新たな子クラスを利用することができる点です. クリエイトプロダクトメソッドをそのまま使うことができますので, コンストラクタの変更に合わせて変更するコードが少なく, 少ない修正で子クラスを追加可能な設計になります. (質問が来ても応えられるか?) new ConcreteProduct1(...) new ConcreteProduct2(...) 生成 return new ConcreteProduct1(...) 生成 コンストラクタ名に依存したコードが増える return new ConcreteProduct2(...)

既存のソフトウェアに対するデザインパターンの適用 手順1. 書籍等に掲載されている適用条件に合う部分を,開発者が見つけ出す 手順2. デザインパターンを適用した結果,設計が改善するか開発者が検討する 手順3.書籍等に掲載されている手順に従い,開発者がソースコードを修正する ソフトウェアが大規模になるほど 開発者の負担は増加する 適用条件を満たす ソフトウェア デザインパターン についての書籍等 発見 実際に修正 続いて,既存のソフトウェアに対してデザインパターンを適用する手順を述べます. まず,書籍などに掲載されているデザインパターンの適用条件に合う部分を ソースコードから見つけ出します. 次に,見つけ出した部分にデザインパターンを適用するため,ソースコードを修正します. 最後に,適用した結果,ソフトウェアの設計が改善したかどうか確認します. 適用後の ソフトウェア 検討 開発者

既存のソフトウェアに対する Factory Methodパターンの適用例 DOMBuilderとXMLBuilderには共通のインタフェース(OutputBuilder)が存在する 新たにテストを行うクラスを追加する Factory Methodパターン適用前 Factory Methodパターン適用後 拡張性の向上 拡張性の問題 子クラス追加に手間がかかる junit::framework::TestCase junit::framework::TestCase AbstractBuilderTest #builder: OutputBuilder ・・・ builder = createBuilder(...); testAddAboveRoot DOMBuilderTest XMLBuilderTest HTMLBuilderTest createBuilder ・・・ builder = createBuilder(...); junit::framework::TestCase protected abstract OutputBuilder createBuilder (...); testAddAboveRoot testAddAboveRoot testAddAboveRoot 既存のソフトウェアに対するデザインパターンの適用について, ファクトリーメソッドパターンの適用例を示します. ファクトリーメソッドパターンの適用を検討すべきコードの特徴は, コードクローンであるメソッドが共通の親クラスを持つクラス対の間に存在する点と, コンストラクタの呼び出し文がコードクローンであるメソッドの間で異なる点です. このコードの構造には2つの問題点があります. 1つは拡張性の問題であり,もう1つはコードクローンの問題です. 拡張性の問題とは, 新たに子クラスを追加して同様の処理を行うように変更があった場合, テストアッドアバブルートゥメソッドを新たに定義することになり, 拡張に手間がかかります. 次にコードクローンとは コードクローンの問題とは,テストアッドアバブルートゥメソッドが増えることにより コードクローンが増えて,保守性が低下するひとつの原因となることです. 例えば,1つのメソッドにバグが存在した場合, 他の2つのメソッドも 修正を検討しなければならなくなります. では,この例に対してファクトリーメソッドパターンを適用していきます. 2つのテストアッドアバブルートゥメソッドを親クラスにまとめたいのですが, 現在の構造では, 呼び出すコンストラクタの種類が異なるためにまとめることができません. そこで,オブジェクトの生成をファクトリーメソッドで間接的に行う構造に変更します. 2つのテストアッドアバブルートゥメソッドのコンストラクタの呼び出し文を 引数,返り値の型の等しいクリエイトビルダーメソッドに置き換えます. 2つのテストアッドアバブルートゥメソッドの内容が揃いましたので, 親クラスにまとめることができます. クリエイトビルダーメソッドを親クラスに抽象メソッドとして定義し, テストアッドアバブルートゥメソッドを親クラスに移動します. これで,ファクトリーメソッドパターンの適用ができました. ファクトリーメソッドパターンを適用したことで, 新たに子クラスを追加するように変更になった場合でも, クリエイトビルダーメソッドを新たに実装するだけで済み, 拡張性が向上し,かつ,コードクローンが減少しています. コードクローン HTMLBuilderTest DOMBuilderTest XMLBuilderTest ・・・ builder = new DOMBuilder(…); ・・・ builder = new DOMBuilder(…); ・・・ builder = new XMLBuilder(…); ・・・ builder = new HTMLBuilder(…); testAddAboveRoot testAddAboveRoot createBuilder createBuilder createBuilder ・・・ builder = new XMLBuilder(…); return new HTMLBuilder(…); return new DOMBuilder(…); return new XMLBuilder(…);

本研究の動機と目的 デザインパターン適用の問題点 Factory Methodパターンの適用条件に合う部分を自動的に検出する手法の実現 デザインパターンの適用条件に合うソースコードを人手で発見することは困難である 大規模ソフトウェアが対象の場合,より困難となる Factory Methodパターンの適用条件に合う部分を自動的に検出する手法の実現 コードクローンの解析 クラスの継承関係の抽出 では,本研究の動機と目的について述べます. 既存のソフトウェアにデザインパターンを適用する上での問題点ですが, デザインパターンの適用条件に合うソースコードを人手で発見することが困難であり, 大規模ソフトウェアが対象の場合,発見はより困難になると考えられます. そこで,ファクトリーメソッドパターンの適用条件に合う部分を 自動的に検出する手法を実現することで, 既存のソフトウェアに対するファクトリーメソッドパターンの適用を支援することを考えました. 提案手法は, コードクローンの解析とクラスの継承関係の抽出, この2つを用いて実現しました.

junit::framework::TestCase 提案手法:適用条件に合う部分を検出 条件 1 兄弟クラス間にメソッド単位のコードクローンが存在する Factory Methodパターン適用前 junit::framework::TestCase 手順 1 コードクローンを検出し,コードクローンを含むクラスの継承関係を解析する DOMBuilderTest XMLBuilderTest testAddAboveRoot testAddAboveRoot 条件 2 コンストラクタ呼び出し文がメソッド間で異なる ・・・ builder = new DOMBuilder(…); ファクトリーメソッドパターンの適用条件は2つあると定めました. 1つは,共通の親クラスを持つ兄弟クラスの間にメソッド単位のコードクローンがある という条件と, もう1つは,呼び出すコンストラクタがメソッドの間で異なるという条件です. この条件を満たす部分をソースコードから検出する手順を定めました. 条件1に対しては,コードクローンを検出し,メソッド単位のコードクローンを含む クラスの継承関係を解析して判定します. 条件2に対しては,メソッドで呼び出すコンストラクタの種類を比較することで判定します. 手順 2 メソッド中のコンストラクタ呼び出し文を比較する ・・・ builder = new XMLBuilder(…);

実験用ツールの概要 入力 出力 コードクローンの検出にはCCFinder[2]を用いた 入力 出力 Javaで記述されたソースコードファイル群 出力 Factory Methodパターンの適用条件に合うメソッド群の位置 それらメソッドに共通した親クラス名 コードクローンの検出にはCCFinder[2]を用いた クラス継承関係 コンストラクタ呼出文の特定 ソースコード 解析部 解析部 デザインパターンが 適用可能な部分の 位置情報 入力 以上の提案手法を実装したツールを試作しました. ジャバで記述されたソースコードのファイル群を入力とし, ツールを使って検出したコードクローンの位置情報と ソースコードを構文解析することで得たクラス継承関係から ファクトリーメソッドパターンの適用条件に合う,メソッド群の位置情報と それらメソッドに共通した親クラス名を出力します. 今回のコードクローンの検出ツールには, シーシーファインダーを使いました. 出力 ソースコード コードクローンの 位置情報 コードクローン 検出部 [2] T. Kamiya, et al., “CCFinder: A multi-linguistic token-based code clone detection system for large scale source code”, IEEE Trans. Softw. Eng., 28(7):654-670, 2002.

実験概要 Factory Methodパターンの適用条件に合う部分の数の調査 提案手法を実装したツールを使って実験を行いました. 目的は2つあり, 1つは,ソフトウェアごとのファクトリーメソッドパターンの適用条件に合う 部分の数の調査であり, もう1つはツールが検出した部分の一例に対し,実際にファクトリーメソッドパターンが 適用可能かどうかの確認です. 8つのジャバで記述されたオープンソースソフトウェアを対象にツールを実行しました.

ツールが検出した部分の数 数万から数十万行のソフトウェア9つから最多で14個検出された Ant 198K 994 2 ANTLR 32K ソースコードの行数 クラスの数 検出部分の数 Ant 198K 994 2 ANTLR 32K 167 1 Azureus 538K 2226 14 JBoss 679K 3372 10 jEdit 168K 922 JHotDraw 90K 487 SableCC 35K 237 Soot 352K 2298 9 WALA 210K 1565 6 ツールの出力した結果です. ソフトウェアごとに,入力したソースコードの行数,抽出されたクラスの数, ツールがファクトリーメソッドパターンを適用可能と判定した部分の数を示しています. 数万から数十万行の8つのソフトウェアからそれぞれ1から14個の部分が検出されました. ツールが出力した中の,アントラーからの検出部分に対して, ファクトリーメソッドパターンの適用が実際に可能かどうか確認しました.

ANTLRへの適用 83個のテストケースを用いて,適用前後で 振る舞いが変化していないことを確認できた 共通のインタフェースが存在しないので Factory Methodパターン適用前 Factory Methodパターン適用後 CodeGenerator CodeGenerator protected abstract OOActionLexer createActionLexer(...); createActionLexer processAction ForSpecialSymbols ・・・ lexer = createActionLexer(…); 83個のテストケースを用いて,適用前後で 振る舞いが変化していないことを確認できた 共通のインタフェースが存在しないので 新たにOOActionLexerインタフェースを定義 CSharpCodeGenerator CppCodeGenerator JavaCodeGenerator CSharpCodeGenerator CppCodeGenerator JavaCodeGenerator ツールが提示した部分に対して Factory Methodパターンを適用できた ファクトリーメソッドパターン適用前は,コードクローンではあるのですが, それぞれの呼び出すコンストラクタが異なるために親クラスにまとめることが できなかった3つのメソッドを, コンストラクタの呼び出し文を, 名前,引数,返り値の型が等しいファクトリーメソッドに置き換えたことで 内容がそろい,親クラスにまとめることができました. 変更の前後でアントラーの振る舞いが変わっていないことを テストケースを使って確認できましたので, ツールが提示した部分に対してファクトリーメソッドパターンを適用できたことが 確認できました. processAction ForSpecialSymbols processAction ForSpecialSymbols processAction ForSpecialSymbols createActionLexer createActionLexer createActionLexer ・・・ lexer = new csharp. ActionLexer(…); lexer = new cpp. lexer = new java. ・・・ lexer = new csharp. ActionLexer(…); ・・・ lexer = new cpp. ActionLexer(…); ・・・ lexer = new java. ActionLexer(…); return new csharp. ActionLexer(...); return new cpp. ActionLexer(...); return new java. ActionLexer(...);

Antへの適用 振る舞いに変化がないことを確認するために JUnitのテストケースを修正する必要がある Factory Methodパターン適用前 Factory Methodパターン適用中 BaseParamFilterReader BaseParamFilterReader getLines 振る舞いに変化がないことを確認するために JUnitのテストケースを修正する必要がある HeadFilter TailFilter HeadFilter TailFilter getLines getLines ファクトリーメソッドパターン適用前は,コードクローンではあるのですが, それぞれの呼び出すコンストラクタが異なるために親クラスにまとめることが できなかった3つのメソッドを, コンストラクタの呼び出し文を, 名前,引数,返り値の型が等しいファクトリーメソッドに置き換えたことで 内容がそろい,親クラスにまとめることができました. 変更の前後でアントラーの振る舞いが変わっていないことを テストケースを使って確認できましたので, ツールが提示した部分に対してファクトリーメソッドパターンを適用できたことが 確認できました. chain chain chain chain newFilter = new HeadFilter(…); ・・・ getLines() newFilter = new TailFilter(…); ・・・ getLines()

考察 Antへの適用 ANTLRへの適用 ツールの出力情報の不足 JUnitのテストケースを修正する必要が生じた インタフェースを追加する必要が生じた コードクローンの量を減らすことができた ツールの出力情報の不足 デザインパターンを適用することで影響を受けるクラス等 テストケースを修正する必要性の有無 考察を述べます. ツールが提示した部分に実際にファクトリーメソッドパターンを適用することができ, コードクローンの量を減らすことができました. また,ファクトリーメソッドパターンの適用の前後で 対称ソフトウェアのアントラーの振る舞いが変わっていないことを テストケースを使って確認できました. 実際にファクトリーメソッドパターンを適用する作業でわかった問題としては, 減らすことのできるコードクローンの量, 編集しなければならないソースコードの量が ユーザから見てわからないという問題がありました.

まとめと今後の課題 まとめ 今後の課題 Factory Methodパターンの適用条件に合う部分を自動的に検出する手法の提案 適用実験でオープンソースソフトウェアから適用候補を検出 2個の検出結果については,実際に適用可能であることを確認 今後の課題 ツールが出力する情報を改善した更なる適用支援 デザインパターンを適用することで影響を受ける部分 テストケースを修正する必要性の有無 Factory Methodパターン以外のデザインパターンについて適用候補を検出 まとめです. 本研究では,ファクトリーメソッドパターンの適用条件に合う部分を ソースコードから自動的に検出する手法を提案しました. 今後の課題としては, 先ほど言った出力情報の改善と, ファクトリーメソッドパターン以外のデザインパターンの適用候補の検出を考えています. 以上で発表を終わります.