2017/02/25
callback hell とか、最近では、Promise hell なんてのも、よく見聞きします。
もっと、古いところでは、 if else の中に if-else が入れ子で入ってしまう、地獄がありました。
今でも、プログラミング歴の浅い、学生のアルバイトの人たちから、ときどき、回避策を尋ねられることがあります。
回避する3つのやり方をご紹介します。
地獄
if (a) {
console.log('A 実行');
if (b) {
console.log('B 実行');
if (c) {
console.log('C 実行');
}
else {
console.log('C 未実行');
}
}
else {
console.log('B 未実行');
}
}
else {
console.log('A 未実行');
}
3階層で入れ子になっています。
この例だと、ifブロックが短いので、まだ見通せますが、実際のプログラムは、もっと、いろいろ処理があるので、入れ子になった if-else を実装していると、今、どこの if を実装しているのか、混乱することがあります。特に、他人が書いたコードだとイライラが募ります。
これが、if-elseの入れ子地獄です。
早期リターン
関数化して、条件が偽のときに、即、リターンで、抜けるというやり方です。
早期リターンは、インデントを浅く保つための、定番の実装テクニックです。
abc();
function abc() {
if (!a) {
console.log('A 未実行');
return;
}
console.log('A 実行');
if (!b) {
console.log('B 未実行');
return;
}
console.log('B 実行');
if (!c) {
console.log('C 未実行');
return;
}
console.log('C 実行');
}
break でフローから離脱
ループ処理 の break で、フローから抜けるというやり方です。
関数にするのが面倒だったり、その場所に実装した方が、わかりやすい場合などは、 do-while と break を使うことで、早期リターンと同じく、入れ子になりません。
do {
if (!a) {
console.log('A 未実行');
break;
}
console.log('A 実行');
if (!b) {
console.log('B 未実行');
break;
}
console.log('B 実行');
if (!c) {
console.log('C 未実行');
break;
}
console.log('C 実行');
} while (false);
Promise で実装
nodejs などは、Promiseで実装してもいいですね。
上の2つに比べると、ちょっとコード量が多めですが。
Promise.resolve()
.then(function() {
return new Promise(function(resolve, reject) {
if (!a) {
console.log('A 未実行');
reject();
return;
}
console.log('A 実行');
resolve();
})
})
.then(function(data) {
return new Promise(function(resolve, reject) {
if (!b) {
console.log('B 未実行');
reject();
return;
}
console.log('B 実行');
resolve();
})
})
.then(function(data) {
return new Promise(function(resolve, reject) {
if (!c) {
console.log('C 未実行');
reject();
return;
}
console.log('C 実行');
resolve();
})
})
;
関連記事
- 2024/01/25 TypeScriptで名前付き引数っぽい実装をする TypeScriptでPythonのように関数呼び出し時に引数名を使って「名前=値」の形式で引数を指定するOptions Objectパターンという技を紹介します。
- 2023/10/17 コードの品質を測定する方法 コードの品質を測定する方法が紹介されていました。計測の自動化に向けて、少しまとめてみました。
- 2023/01/26 デメテルの法則 「直接の友達とだけ話すこと」というプログラミングのお約束です
- 2020/06/15 PySparkの分散される処理単位であるクロージャと共有変数の仕組み Spark では、処理が分散されて、複数のノードやスレッドで実行されますが、分散される処理の塊を、どう配信しているのか?加えて、複数のタスク間でのデータの共有とか、集約するための仕組みがどうなっているのか?少しだけ説明します。
- 2019/09/24 「オブジェクト指向エクササイズ」でクセの強いコードを矯正しよう よくできたコードは、パッと見で、”なんか違う”と感じさせるところがあり、あぁ、このコードを書いた人はデキるって思わせるものですが、そんなコードを書くためには、どうしたらよいんでしょうか?そのヒントが「オブジェクト指向エクササイズ」にあります。