スライド 1 - Software Engineering Laboratory

同時変更が生じた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