判断と処理を分けると、読みやすくなり、テストやデバッグをしやすくなります。
例は javascriptで書いています。
1. 初期バージョン
最初に書くバージョンはだいたいこんな感じです。
「もろもろの処理」は、複数行だったり、if文やfor文を含むことがあります。
function my_func (a) {
if (a > 10) {
if (a > 20) {
if (a > 30){
もろもろの処理_1
} else {
もろもろの処理_2
}
} else {
もろもろの処理_3
}
} else {
もろもろの処理_4
}
}
Code language: JavaScript (javascript)
2. if文の本体を1行にします。
if文の本体をメソッド化して1行にします。if文の本体を短くしたほうが、ifの流れが読みやすいです。そして、my_func_1からmy_func_4のテストケースを書けるようになります。
function my_func (a) {
if (a > 10) {
if (a > 20) {
if (a > 30){
my_func_1();
} else {
my_func_2();
}
} else {
my_func_3();
}
} else {
my_func_4();
}
}
function my_func_1() {
もろもろの処理_1
}
function my_func_2() {
もろもろの処理_2
}
function my_func_3() {
もろもろの処理_3
}
function my_func_4() {
もろもろの処理_4
}
Code language: JavaScript (javascript)
3. 「判断」をメソッド化します。
「判断」をテストするために、メソッド化します。my_func_1からmy_func_4の分岐は、単純なswitch文にします。変数aの値によって、4通りの処理があることが一目瞭然になりました。
function my_func (a) {
var num = case_number(a);
switch (num) {
case 1:
my_func_1();
break;
case 2:
my_func_2();
break;
case 3:
my_func_3();
break;
case 4:
default:
my_func_4();
break;
}
}
function case_number(a) {
var num = 0;
if (a > 10) {
if (a > 20) {
if (a > 30){
num = 1;
} else {
num = 2;
}
} else {
num = 3;
}
} else {
num = 4;
}
return num;
}
function my_func_1() {
もろもろの処理_1
}
function my_func_2() {
もろもろの処理_2
}
function my_func_3() {
もろもろの処理_3
}
function my_func_4() {
もろもろの処理_4
}
Code language: JavaScript (javascript)
4. 条件を整理して、if文のネストを浅くします
条件を整理して、デシジョンテーブルを作ります。デシジョンテーブルにしたがって、if文を実装します。コメントにデシジョンテーブルを書いておきます。
/*
| # | a | action |
| - | ----- | --------- |
| 4 | <= 10 | my_func_4 |
| 3 | <= 20 | my_func_3 |
| 2 | <= 30 | my_func_2 |
| 1 | > 30 | my_func_1 |
*/
function case_number(a) {
var num = 0;
if (a <= 10) {
num = 4;
} else if (a <= 20) {
num = 3;
} else if (a <= 30) {
num = 2;
} else {
num = 1;
}
return num;
}
Code language: JavaScript (javascript)
5. my_funcを別クラスにする
my_func関連のコードが長くなったら、別ファイルの別クラスにします
function my_func (a) {
(new MyFunc()).main(a);
}
Code language: JavaScript (javascript)
/*
| # | a | action |
| - | ----- | --------- |
| 4 | <= 10 | my_func_4 |
| 3 | <= 20 | my_func_3 |
| 2 | <= 30 | my_func_2 |
| 1 | > 30 | my_func_1 |
*/
class MyFunc {
main(a) {
var num = case_number(a);
switch (num) {
case 1:
my_func_1();
break;
case 2:
my_func_2();
break;
case 3:
my_func_3();
break;
case 4:
default:
my_func_4();
break;
}
}
case_number(a) {
var num = 0;
if (a > 10) {
if (a > 20) {
if (a > 30){
num = 1;
} else {
num = 2;
}
} else {
num = 3;
}
} else {
num = 4;
}
return num;
}
my_func_1() {
もろもろの処理_1
}
my_func_2() {
もろもろの処理_2
}
my_func_3() {
もろもろの処理_3
}
my_func_4() {
もろもろの処理_4
}
}
Code language: JavaScript (javascript)