ほとんどの人は、メソッドを見て、単一の出口点を想定するのが好きです。ループの途中でリターンを補間すると、フローが少し分割され、この仮定が妨げられます。そのため、多くの人が「きれいではない」という議論をします。本当に汚いことは何もありませんが、プログラムの「人間」の読者は、その流れをより明確に理解するために、メソッドをより深く掘り下げる必要があります。あなたの論理の流れを理解するために人々がしなければならない精神的な推論の量を減らすためにあなたができることは何でも良いことと考えられています。
メソッドの内部を読まずにメソッドを一瞥し、メソッドが何を実行し、どこで終了するかを全体的に理解できれば、作成者は良い仕事をしました。問題は、最初はうまくいくことを意味する方法が時間の経過とともに成長し、メンテナがそれを理解するために演習で複数の状態を精神的に調整することを余儀なくされるときに発生します。
良い例は、一部の人が良い習慣と見なしている古典的なガード条項です。これは、続行する前に状態またはパラメーターの有効性をチェックする方法です。メソッドに間違ったものが与えられた場合、続行したくありません。この偽のコードを参照してください:
public void doSomethingCool(Object stuff) {
if(weWereNotExpectingThis(stuff)) return; //guard clause
while(somethingHappens()) {
doSomethingCool();
}
return;
}
誰かがやって来て、「かっこいい!メソッドの途中でreturnステートメントを使用しても大丈夫です!」と言います。彼らは変更を加え、それは次のようになります。
public void doSomethingCool(Object stuff) {
if(weWereNotExpectingThis(stuff)) return; //guard clause
while(somethingHappens()) {
if(somthingHasChanged()) return; //because my team likes early exits, Yay!
else {
doSomethingCool();
}
}
return;
}
まだそれほど粗末ではありませんが、ますます多くの変更が加えられ、最終的には次のようになります。
public void doSomethingCool(Object stuff) {
if(weWereNotExpectingThis(stuff)) return; //guard clause
while(somethingHappens()) {
if(somthingHasChanged()) return;
else if(weDetectNewInput()) {
doSomethingCool();
} else {
doSomethingBoring();
if(weDetectCoolInput()) {
doSomethingCool();
continue;
}
return;
}
}
return;
}
これで、これがどこに向かっているのかがわかります。どこにジャンプするのか、何が起こっているのかを一目で理解するのは難しい。