同時変更が生じたTemplate Method パターンの適用事例の調査 ○齋藤 晃,吉田 則裕, 松下 誠, 井上 克郎 大阪大学 情報科学研究科 井上研究室 2009/2/23 1 目次 背景 問題点 調査内容 調査方法 提案メトリクスの説明 調査結果 評価とまとめ 2 背景:デザインパターンの重要性 デザインパターンとは オブジェクト指向設計に関する典型的な問題の解決策 クラスの保守性・再利用性が向上 熟練者が過去に蓄積したノウハウ Gammaらの提案した23個のパターンが有名[1] Template Methodパターン デザインパターンの1例 多くの既存コードで使用されており,ソースコードから検出も 比較的容易 他のパターンの一部としてよく使われている [1] E .Gamma, R. Helm, R. Johnson, and J. M. Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley, 1995. 3 Template Methodパターン 親クラスのあるメソッド内で抽象メソッドを呼ぶ Figure PrimitiveOperation abstract draw(Graphics g) drawFigure() ・・・・・・・・・・・ TemplateMethod 抽象メソッド void drawFigure(){ g.cleargraphics(); draw(g); ・・・ } 1つ以上のクラスが継承 Circle Rectangle Triangle draw(Graphics g) draw(Graphics g) draw(Graphics g) 抽象メソッドをオーバーライド クラス追加 Figure Figure Figure Figure f1 f1 f2 f2 == == new new new new Circle(); Circle(); Rectangle(); Rectangle(); Figure f3 = new Triangle(); f1.drawFigure(); f2.drawFigure(); f1.drawFigure(); f2.drawFigure(); 異なる処理を f3.drawFigure(); 共通のインターフェースで動作 変更範囲を限定することで保守性が向上 4 問題点(1/2) Template Methodパターンの適用事例の中には,安定性が 低いものが存在 安定性が低い…ソフトウェア保守において多くのクラスに変更が生じる ・・・・・ Version1.0 Version1.1 Version1.2 1つだけ変更 Version1.3 ・・・・・ Version1.0 Version1.1 Version1.2 複数のクラス が変更 Version1.3 多くのクラスに同時に変更が生じるのは望ましくない 5 問題点(2/2) –同時変更の例 関連するクラス全てを同時に変更する必要がある Figure abstract draw(Graphics g) drawFigure() abstract draw() drawFigure() Circle Rectangle Triangle draw(Graphics g) draw(Graphics g) draw(Graphics g) 変更 変更 変更 Figure 変更 Circle Rectangle Triangle draw() draw() draw() パターンの適用により同時変更が生じる 6 研究内容 デザインパターンの安定性を低下させる要因を調査 安定性が低い‥同時変更が生じやすい 安定性を低下させる要因は何か? 仮説:子クラスの処理内容の差異が大きいほど 同時変更が生じやすい 仮説を設定した理由 差異が大きいと子クラスごとに処理を切り替えることが 難しくなり,親クラスに変更が波及する 同時変更が生じやすくなる 7 仮説の検証方法 仮説 子クラスの処理内容の差異が大きいほど同時変更が生じやすい 検証方法 手順1:同時変更の検出 同時変更が生じたクラスとそうでないクラスに分類 手順2:クラスの処理内容の差異を表すメトリクスを定義 手順3:それぞれのメトリクス値を比較・評価 マン・ホイットニーのU検定を使用 8 調査する同時変更 抽象メソッドのメソッド定義の変更 抽象メソッドの数の変更 Template Methodの消滅 これらの変更の有無を 調査 SuperClass SuperClass templateMethod() primitiveOperation() templateMethod() anotherMethod() primitiveOperation() primitiveOperation(int) primitiveOperation2() SubClass1 SubClass2 primitiveOperation() primitiveOperation() 変更前 SubClass2 SubClass1 primitiveOperation() primitiveOperation() primitiveOperation(int) Operation1() primitiveOperation(int) Operation() primitiveOperation2() primitiveOperation2() 変更後 9 手順1.同時変更の検出 抽象メソッドが変更の前後で以下の条件を満たせば,同時変 更は生じていないと判定 条件a: 同一のクラス名を持つクラスで定義されている YES NO クラス消滅 条件b: 同一のメソッド名を持つTemplate Methodから呼び出されている YES NO Template Methodが同一のクラス名を持つクラスで定義されている NO YES 抽象メソッドの数の変更 Template Method消滅 条件c: 同一のメソッド定義を持つ YES 同時変更なし NO Primitive Operationの 定義が変更 10 手順2.処理内容の差異を表すメトリクスを計測 クラスの処理内容の差異を表すメトリクス を定義 型名類似度SimT メソッド内で利用された型名に着目 識別子名類似度SimⅠ メソッド内で利用された型名を除く識別子名に着目 11 型名類似度SimT 1/2 メソッド内の一時変数・参照変数の型名と呼び出される メソッドの引数・戻り値の型名の一致割合 Scanner1クラスのnewScannerメソッド protected Scanner newScanner() { ZipScanner zs = new ZipScanner(); zs.setEncoding(encoding); defaultEncoding = false; String return zs; boolean } AbstractScanner templateMethod abstract newScanner() Scanner1 Scanner2 newScanner() newScanner() Scanner2クラスのnewScannerメソッド protected Scanner newScanner() { TarScanner zs = new TarScanner(); defaultEncoding = false; return zs; boolean } 抽象メソッドをオーバーライド メトリクス計測対象となるメソッド 12 型名類似度SimT 2/2 メソッド内の一時変数・参照変数の型名と呼び出される メソッドの引数・戻り値の型名の一致割合 Scanner1クラスのnewScannerメソッド protected Scanner newScanner() { ZipScanner zs = new ZipScanner(); zs.setEncoding(encoding); defaultEncoding = false; String return zs; boolean } Scanner2クラスのnewScannerメソッド protected Scanner newScanner() { TarScanner zs = new TarScanner(); defaultEncoding = false; return zs; boolean } T1 = {boolean, String, ZipScanner} T2 = {boolean, TarScanner} メトリクス値 n T i SimT = i 1 n = 0.25 T i i 1 13 識別子名類似度SimⅠ 1/2 メソッド内の一時変数・参照変数の識別子名と呼び出されている メソッド名の一致割合(ただし型名は除く) Scanner1クラスのnewScannerメソッド protected Scanner newScanner() { ZipScanner zs = new ZipScanner(); zs.setEncoding(encoding); defaultEncoding = false; return zs; } AbstractScanner templateMethod abstract newScanner() Scanner1 Scanner2 newScanner() newScanner() Scanner2クラスのnewScannerメソッド protected Scanner newScanner() { TarScanner zs = new TarScanner(); defaultEncoding = false; return zs; } 抽象メソッドをオーバーライド メトリクス計測対象となるメソッド 14 識別子名類似度SimⅠ 2/2 メソッド内の一時変数・参照変数の識別子名と呼び出されている メソッド名の一致割合(ただし型名は除く) Scanner1クラスのnewScannerメソッド protected Scanner newScanner() { ZipScanner zs = new ZipScanner(); zs.setEncoding(encoding); defaultEncoding = false; return zs; } Scanner2クラスのnewScannerメソッド protected Scanner newScanner() { TarScanner zs = new TarScanner(); defaultEncoding = false; return zs; } Ⅰ1 = {defaultEncoding, zs, encoding, setEncoding} Ⅰ2 = {defaultEncoding, zs} メトリクス値 n I SimⅠ = i i 1 n I = 0.5 i i 1 15 変更の検出およびメトリクス計測の流れ ソースコード ソースコード ソースコード バージョン1.0 バージョン1.1 バージョン1.2 バイトコード バージョン1.0 バイトコード バイトコード バージョン1.1 バージョン1.2 入力:Javaソースコード :Javaバイトコード 1.Template Methodパターン検出 デザインパターン 検出ツール[2] メソッド名,クラス位 置などの情報を取得 調査ツール メトリクス 計測ツール 分類処理部 2.変更の有無による 分類 分類データ 変更有 パターン 変更無 パターン 3.メトリクス計測 4.変更の有無とメトリクス値の関係を評価 出力:メトリクス値 [2]Nikolaos Tsantalis,Design pattern detection using similarity scoring. IEEE Transactions on Software Engineering, 2006 16 メトリクス計測結果 調査対象:オープンソースソフトウェア3種 ArgoUML, JFreeChart, JHotDraw 変更なし:120個,変更あり:44個 第3四分位 型名類似度 類似度 識別子名類似度 類似度 中央値 第1四分位 変更なし 変更あり 変更なし 変更あり 同時変更が生じたパターンの適用事例ほうが類似度が低い傾向 マン・ホイットニーのU検定で有意差 型名類似度:P=0.0014, 識別子名類似度:P=0.0053 17 結果の分析 提案した類似度が低く,変更が生じた例 FigCallAction::layoutActivations SimⅠ = 0.0, SimT = 0.0 protected void layoutActivations() { if (!getSrcFigObject().hasActivations()) { getSrcFigObject().makeActivation( getSrcFigObject().getObjectNode(), (Node) getSrcLinkPort()); ・・・ } else { ・・・ 処理を記述 } } FigCallAction::layoutActions FigLink layoutEdge abstract layoutActivations FigCallAction FigReturnAction layoutActivations layoutActivations protected void layoutActivations(){ //TODO: Auto-generated method stub } 処理を記述していない 次のバージョンでTemplate Methodが消滅 特別研究発表会 処理内容の差異が原因で,Template Methodが消滅 2009/2/23 18 本調査の妥当性 本調査の妥当性に影響を及ぼす要因 適用事例検出ツールの誤検出 しかし,使用したツールは適合率が高く,対象とした Template Methodパターンは検出が比較的容易で あるため,影響は小さいと考えられる クラス名のみが変更されたときの誤検出 クラス内部が変更されずに,クラス名のみが変更さ れた場合,クラスが消滅したと扱われる まとめと今後の課題 まとめ Template Methodパターンの適用事例の安定性を低下させる 要因を調査 識別子名類似度・型名類似度の安定性との関係 マン・ホイットニーのU検定で有意差 今後の課題 他のパターンへの適用 同時変更が生じやすい適用事例を自動的に特定 安定性の低い適用事例が実装されたら警告する機能を統合 開発環境に実現 20 ご静聴ありがとうございました 2009/2/23 21 質疑応答 22 関連研究 Biemanらは,デザインパターンの適用事例を用いたプログ ラムの評価を行うために,以下の仮説を調査 仮説1. 規模の大きなクラスは変更されやすい. 仮説2. デザインパターンが適用されているクラスはそうでないクラスより変更さ れにくい. 仮説3. 継承によって再利用されているクラスはそうでないクラスより変更されに くい. 仮説1に従う傾向が得られたが,仮説2,3に反 する結果となった 本調査ではデザインパターンの適用事例の評価基準として変 更頻度が高くなる要因に着目した [2] J.Bieman, D.Jain, and H.Yang. OO design patterns, design structure, and program changes: an industrial case study. ICMS ’01 , pp. 580–589, 2001. [3] J.Bieman, G.Straw, H.Wang, P.Munger, and R.Alexander. Design patterns and change proneness: An examination of five evolving systems. METRICS ’03 , pp. 40–49, 2003. 検定について 得られたデータは正規分布とは言えなかった 両側に値が寄っているため コルモゴロフ-スミルノフ検定(KS検定)で確認 マン・ホイットニーのU検定 ノンパラメトリック検定の1つ 順位和による差異を検定 帰無仮説:2群の代表値に差がない(代表値R1= R2:) 対立仮説:2群の代表値に差がある(代表値R1< R2:片側検定) 特別研究発表会 2009/2/23 24 仮説2について 仮説2:子クラスの処理内容の規模が大きいほど変更 されやすい LOC平均 LOC平均を計測 U検定で有意差なし (P= 0.139) 処理内容の規模と同時変更の 差異に相関は見られなかった 平均 LOC 変更なし 特別研究発表会 変更あり 2009/2/23 25 LOC分散について 子クラスの抽象メソッドの差異を計測 対数(標準偏差)で表示 類似度 変更なし 変更あり U検定でP値0.0467 特別研究発表会 2009/2/23 26 計測したメトリクス値(1/2) LOC平均 LOC分散 特別研究発表会 2009/2/23 27 計測したメトリクス値(2/2) 識別子類似度 型名類似度 特別研究発表会 2009/2/23 28 変更結果の例 子クラスの処理差異が変更の要因となっているか? SubClass1 SimⅠ = 0.0, SimT = 0.0 protected boolean isValidElement(MBase o){ return o instanceof MAssociationRole … } SubClass2 protected boolean isValidElement(MBase elem){ return elem instanceof MAssociation … } 引数がObjectに変化 処理差異が変更の要因になっている 特別研究発表会 2009/2/23 29 計測したメトリクスについて 型名類似度と識別子名類似度の相関 相関係数0.567 変更なし:0.511 変更あり:0.803 LOC分散 U検定でP値0.0467 危険率5%で有意差 変更なし 変更あり 250 60 200 50 40 150 30 100 20 50 10 0 0 0 5 10 15 20 25 30 35 40 45 50 55 特別研究発表会 0 5 10 15 20 25 30 35 40 45 50 55 60 2009/2/23 31 LOC平均 U検定でP値0.1392 変更あり 変更なし 50 45 40 35 30 25 20 15 10 5 0 250 200 150 100 50 0 0 10 20 30 40 50 60 70 80 90 100 110 特別研究発表会 0 10 20 30 40 50 60 70 80 90 2009/2/23 32 識別子名類似度 U検定で有意差(P=0.0053) 変更が生じなかったパターン数 変更が生じたパターン数 120 120 100 100 80 パターン 60 数 40 パターン 数 80 60 40 20 20 0 0 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 識別子類似度 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 識別子類似度 型名類似度 U検定で有意差(P=0.0014) 変更が生じなかったパターン数 80 70 60 50 パターン 40 数 30 20 10 0 変更が生じたパターン数 80 70 60 50 パターン 40 数 30 20 10 0 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 型名類似度 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 型名類似度 計測するメトリクス(1/2) 子クラスのLOC平均LOCa 子クラスのLOC分散LOCv 識別子類似度SimⅠ メソッド内で定義される一時変数・参照変数の識 別子名と呼び出されている関数名の一致割合 型名類似度SimT メソッド内で定義される一時変数・参照変数の型 名と呼び出される関数の引数・戻り値の型の一 致割合 特別研究発表会 2009/2/23 35 同時変更の判定アルゴリズム 1/2 変更の前後で以下の条件を満たせば,同時変更は生じていな いと判定 条件1.同一のクラス名を持つクラスで定義されている 条件2.同一のメソッド名を持つTemplate Methodから呼び出されている 条件3.同一のメソッド定義を持つ 36
© Copyright 2024 ExpyDoc