本研究の概要
クラスサイズメトリクスを用いたソフトウェア変更量予測に関する考察
望月尚美（愛媛大学大学院 理工学研究科 情報工学専攻）

阿萬裕久 山田宏之 野田松太郎（愛媛大学 工学部 情報工学科）

目的
オブジェクト指向ソフトウェアの変更・発展に伴う変更量とクラスサイズ との関係解析 を行い，ソフトウェア技術者 に対して開発基準を提供．
方法
オープンソースソフトウェア に対し，バージョンアップに伴う変更量の測定及びクラスサイズの測定．
結果
測定結果を分析し，ソフトウェア変更量 をクラスサイズによって予測・判別するための閾値を算出．

研究背景
l

研究背景

ハードウェアの進歩により，ソフトウェアは大規模かつ高機能なものが求められている．
ソフトウェアの開発・保守コストの増大

ソフトウェア品質の評価・予測やコストの見積もりが必要
ライフサイクルコストにおいて最も大きいといわれている保守コストに注目．
l 保守において施された変更の量とクラスサイズとの関係について考察．
ll

一般的にオブジェクト指向設計は開発性・保守性に優れているといわれている．
現実には技術者の力量・経験に依存

ソフトウェア変更・発展に伴う変更量
ソフトウェアの変更量
ソフトウェアのバージョンアップに伴うソースコードの変更行数．
連続したn 行のコードを連続した m 行のコードと置換連続した m 行のコードを挿入
l連続したn 行のコードを削除
ll

テスト工数にも強く影響

変更行数の測定方法(1) ソースコードからコメント文を除去．
(2) UNIX コマンド「diff」を用いて，あるバージョン とその直後のバージョン とを比較．
(3) diff コマンドの出力結果から変更行数を測定．

※コメント文・空文は除く．

1diffを用いた出力ファイルの例
public class HelloWorld {public static void main(String[] args){
for ( int i = 0; i < 10; i++ ){System.out.println(“HelloWorld!!”);
System.out.println(“Hello”);
public class HelloWorld {}public static void main(String[] args){}for ( int i = 0; i < 5; i++ ){}System.out.println(“HelloWorld!!”);

version 1.0: HelloWorld.java}

System.out.println(“END”);}}

version 1.1: HelloWorld.java*** 1，8 ****
diff の出力
public class HelloWorld {public static void main(String[] args){!
for ( int i = 0; i < 10; i++ ){System.out.println(“HelloWorld!!”);
削除
System.out.println(“Hello”);}}
修正
削除・追加の合計数 ＝ 変更行数
} 修正・--1，8---（※但し，修正は変更前と変更後の行数を比較し大きい方を用いる）
public class HelloWorld {public static void main(String[] args){!
for ( int i = 0; i < 5; i++ ){!
System.out.println(“[” + i + “]”);
System.out.println(“HelloWorld!!”);}
version
1.0 からversion 1.1 へ追加+System.out.println(“END”);

バージョンアップしたときの変更行数：4}*** 1，8 ****
diff の出力
public class HelloWorld {public static void main(String[] args){!
for ( int i = 0; i < 10; i++ ){System.out.println(“HelloWorld!!”);
削除
System.out.println(“Hello”);}}
修正
削除・追加の合計数 ＝ 変更行数
} 修正・（※但し，---修正は変更前と変更後の行数を比較し大きい方を用いる）
1，8 ---public class HelloWorld {public static void main(String[] args){!
for ( int i = 0; i < 5; i++ ){System.out.println(“HelloWorld!!”);}
version
1.0 からversion 1.1 へ追加+バージョ
System.out.println(“END”);
ンアップしたときの変更行数：３}}

クラスサイズ
各バージョンにおけるクラスのサイズ をメトリクス Stmts（Statements）で測定．
メトリクス Stmts
クラスにおけるメソッドの宣言文と実行文の数．
（※ ≠ LOC：プログラム行数）
コーディングスタイルに依存しない測定．

}

Java 言語におけるメソッドの宣言文と実行文の一覧
ローカル変数宣言文 l ラベル付き文l メソッド呼び出し文
式文
l クラスインスタンス生成文
l 代入文
l If 文l インクリメント
文l While 文
l デクリメント文l For 文l Break 文l Switch 文
l Synchronized 文
l Do 文l Continue 文
l Try 文l Return 文l Throw 文
llStmtsの測定方法
Stmts はソースコードから測定可能．
Javaプログラムの構文解析が必要．
JavaソースコードをXML（JavaML）へ変換．
Stmts の測定が容易になる．
（１）コメント文を除去したソースコードを JavaML に変換．
IBM が提供しているコンパイラ jikes を用いる．

（２）JavaMLファイルからメソッドの宣言文と実行文の数を測定．（対応するタグの数を数える）

2

Stmtsの測定方法
変換前のJavaプログラム
public class HelloWorld {public static void main(String[] args){
int i = 0 ;while( i < 5 ){System.out.println("Hello World!!");
i++;
}
}
}

JavaML の一部<method name="main" visibility="public" static="true"><type name="void" primitive="true"/><formal-arguments><formal-argument name="args" id="HelloWorld:frm-9"><type name="String" dimensions="1"/></formal-argument></formal-arguments><block><local-variable name="i" id="HelloWorld:var-26"><type name="int" primitive="true"/><literal-number kind="integer" value="0"/></local-variable><loop kind="while"><test><binary-expr op="&lt;"><var-ref name="i"/><literal-number kind="integer" value="5"/></binary-expr></test><block><send message="println"><target><field-access field="out"><var-ref name="System"/></field-access></target><arguments><literal-string value="Hello World!!"/></arguments></send><unary-expr op="++" post="true"><var-ref name="i"/></unary-expr></block></loop></block></method>

JavaML の一部

public static void main(String[] args){ ・・・・・} に対応<method name=“main” visibility=“public” static="true"><type name="void" primitive="true"/><formal-arguments><formal-argument name="args" id="HelloWorld:frm-9"><type name="String" dimensions="1"/></formal-argument></formal-arguments>

・・・・・・・</method>

int i = 0 に対応<local-variable name="i" id="HelloWorld:var26"><type name="int" primitive="true"/><literal-number kind="integer"value="0"/></local-variable>
i++ に対応<unary-expr op="++" post="true"><var-ref name="i"/></unary-expr><method name="main" visibility="public" static="true"><type name="void" primitive="true"/><formal-arguments><formal-argument name="args" id="HelloWorld:frm-9"><type name="String" dimensions="1"/></formal-argument></formal-arguments><block><local--variable name="i" id="HelloWorld:var<local
id="HelloWorld:var -26"><type name="int" primitive="true"/><literal-number kind="integer" value="0"/></local-variable><loop kind="while"> <test>

変更・発展のための変更量とクラスサイズとの関係l

一般的にクラスサイズ が大きくなれば，変更・発展のための変更量も多くなると考えられる．

メソッドにおける<binary--expr op="&lt;"> <var-ref name="i"/><binary
宣言文と実行文<literal-number kind="integer" value="5"/></binary-expr></test><block><send message="println">に対応<target><field-access field="out"><var-ref name="System"/></field-access></target><arguments><literal-string value="Hello World!!"/></arguments></send><unary--expr op="++" post="true"> <var-ref name="i"/><unary</unary-expr></block></loop></block></method>

バージョンアップに伴うソースコードの変更量が特に多くなる場合とそうでない場合を予測・判別するための一つの閾値について考える．

ソフトウェア開発において品質管理の目安にできる

3

分析方法

分析方法

1. あるクラス C に対して，複数のバージョン (v 1，v 2，… v n)を用意測定を行ったクラスのうち，特に変更が大きかったサンプル（変更行数の上位α％）に着目．

2. あるバージョン のクラス C に対して，直後のバージョンと比較し変更行数 を算出※αは品質管理者 が経験的に決定．

C (vi) とC (vi+1) を比較

3. クラスサイズメトリクス Stmts を用い，各バージョンでのクラスサイズ を測定

閾値を導入し，変更行数が特に多くなる場合とそうでない場合とを Stmts 値でもって予測・判別することを考える．

C (vi) の Stmts 値を測定

測定データの分布測定実験と結果分析のを含め，総クラス数：15405個）

特に変更が大きかったクラス（変更行数の上位α％）に着目．
※αは品質管理者 が経験的に決定．

例えば，•バージョンAとバージョンBとの間での変更行数＝201•バージョンAでのクラスサイズ：
Stmts値＝24500
400

変更行数

測定対象
オープンソースソフトウェア Relaxer，JBoss，JEditに含まれていた Java プログラム ．（複数の異なるバージョンのも

300
200

201100

今回は変更行数の上位5% に着目し，分析を実施．

0

閾値を導入し，変更行数が特に多くなる場合とそうでない場合とを Stmts 値でもって予測・判別することを考える．

0

予測・判別するための閾値τ
変更行数を予測・判

2450
Stmts 値

100

予測・判別するための閾値τ

別するための閾値τ
500

500
変更行数
上位α％

判定誤り

300
200
100

判定誤り

400
変更行数

変更行数

400

300
200
100

00050
Stmts 値

100050Stmts 値1004予測・判別するための閾値τ
500

500
判定誤り

400
変更行数

400
変更行数

予測・判別するための閾値τ300
2001000200
100

判定誤り

0300

050
Stmts 値

1000

予測・判別するための閾値τ
500
判定誤り

判定誤りが最小となるような閾値τを捜す

300
200
100500
判定誤り

400

判定誤りが最小となるような閾値τを捜す

300
200
100

判定誤り

00100

予測・判別するための閾値τ

変更行数

変更行数

400

50
Stmts 値

判定誤り

050
Stmts 値

100

予測・判別するための閾値τ

050
Stmts 値

100

測定実験と結果分析

測定データの分割表

変更行数

上位α%

その他

Stmts 値
τ未満
τ以上
E1
S1
S2
E2

予測・判別誤差の大きさε（τ）：

計
N1
N2

測定対象
オープンソースソフトウェア Relaxer，JBoss，JEditに含まれていた Java プログラム ．（複数の異なるバージョンのものを含め，総クラス数：15405個）

測定を行ったクラスのうち，特に変更が大きかったサンプル（今回は変更行数の上位5％）に着目し，分析．

ε（τ）=E1/N1 + E2/N25

閾値τに対する誤り率の合計の変化
誤り率 の合計：ε(τ)ε（τ）が最小となるτ=113
1
予測・判別誤差が最小．
閾値τ = 113

0.7（※逐次比較により容易に検出可能）

0.4
01000

閾値τ2000

3000

この結果の持つ意味
n Stmts 値≧113のクラスではバージョンアップに伴う変更量が特に多い傾向にあった
113未満となるよう開発するとよい．
（参考）
文の数プログラム行数113
250行程度
おおよそ対応※実験データによる

τ= 113 における有効性の検討
n（※コメント文を除く）

まとめ

新たに 556個 のサンプルを取得し，実験を実施

変更行数 上位5%
その他

計
15398

541

143

変更・発展に伴う変更量が多かったクラスに着目し，その変更量とクラスサイズとの関係解析を実施．
l 閾値を導入し，変更行数が特に多くなる場
合とそうでない場合とをStmts 値でもって予測・判別する方法について検討．
lStmts 値
τ未満 τ以上
510

変更行数の多いクラスのうち 約67% をトータルで約73％の予測判別に成功
変更行数の少ないクラスのうち 約74% を
今後の課題：予測精度の向上
それぞれ（予測）判別できた

今後の課題
n

他のメトリクスを用いた場合の実験・検討．

n

複数のメトリクスを用いた判別分析による予測精度の向上．

6