โ if-else-return โ ๐ข if-return-return
์ด๋ ์๊ฐ๋ถํฐ ์กฐ๊ฑด๋ฌธ์ ์ธ ๋ ์ฃผ์ (main clause)์ ํด๋นํ๋ ์ผ์ด์ค์ธ์ง๋ฅผ ๋จผ์ ์ฒดํฌํ๋ ๊ฒ์ด ์๋๋ผ
async function onSubmitForm () {
if (isValidForm) {
const formattedForm = formatForm()
await submitForm(formatForm())
} else {
showErrorMsg()
}
}
์์ธ์ ์ ํด๋นํ๋์ง๋ฅผ ย ๋จผ์ ์ฒดํฌํ๊ธฐ ์์ํ๋ค.
async function onSubmitForm () {
if (!isValidForm) return showErrorMsg()
const formattedForm = formatForm()
await submitForm(formatForm())
}
๋ฟ๋ง ์๋๋ผ if
์ ๊ผญ ํ ์ธํธ์ฒ๋ผ ์ผ๋ else
๋ก ์์ธ์ฒ๋ฆฌ๋ฅผ ํ๋ ๋์ ์์ธ์ ์๋ํ ์ฒ๋ฆฌ๋ฅผ ํ๋ฉด์ if
๋ธ๋ก ์์์ ๋ฐ๋ก return
์ ์์ผฐ๋ค. ๊ฐ์๋ฅผ ๋ค์ผ๋ฉฐ ๋ฐ๋ผ ์น ์ฝ๋๋ ์๋์ด ๊ฐ๋ฐ์๋ค์ ์ฝ๋๋ก๋ถํฐ ๋ฐฐ์ด ๊ฒ์ธ๋ฐ nesting์ ์ค์ผ ์ ์์ด ๊ฐ๋
์ฑ์ด ๋ ์ข์์ก๊ณ ย ๋ ์์ธ ์ผ์ด์ค๋ฅผ ํจ์ ์ฒซ๋จธ๋ฆฌ์์ ๋ชจ๋ ์ฒดํฌํ๋ค๊ณ ๊ฐ์ ํ๊ณ ์ฃผ์ ๋ก์ง์ ์์ฑํ๊ธฐ๋๋ฌธ์ ์์ฌ์ด ๋์๋ค.
๊ทธ๋์ ย ๊ทธ ๋ค๋ก ์ฝ๋ ๋ฆฌ๋ทฐ๋ฅผ ํ ๋๋ ํ์์ด if
-else
-return
๊ตฌ์กฐ๋ก ์ง ์ฝ๋๋ฅผ ๋ณด๋ฉด ์์ฐํ if
-return
-return
๊ตฌ์กฐ๋ก ๋ฐ๊พธ๊ณ ํ ์ถฉ๋์ด ๋ค์๋ค. ํ์ง๋ง '๊ฐ๋
์ฑ์ด ์ข๋ค'๊ฑฐ๋ '์์ฌ์ด ๋๋ค'์ ๊ฐ์ ๊ฒ์ด ๋ค์ ์ฃผ๊ด์ ์ธ ์ธ์ ๋ง ๊ฐ์ง๊ณ ์ ๋์๊ฐ๋ ์ฝ๋๋ฅผ ๊ณ ์ณ์ฐ์๊ณ ํ๊ธฐ์๋ ์ค๋๋ ฅ์ด ์์๋ค. ๋ ํผ์ ๊ทธ๋ ๊ฒ ์๊ฐํ๋๊ฑด ์๋์๋์ง Stack Overflow์๋ if
-else
-return
๊ฐ ๋์์ง if
-return
-return
์ด ๋์์ง์ ๋ํ ์ด๋ค ํ ๋ก ์ด ์งํ์ค์ด์๋ค(๐ "It is more efficient to use if-return-return or if-else-return?"). ํด๋น ์ฐ๋ ๋์์๋ ๋ ์คํ์ผ๊ฐ์ ์ฑ๋ฅ ์ฐจ์ด๋ ์๋ค๊ณ ํ๋๋ฐ ๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ if
-return
-return
์ ๋ณด๋ค ๋์ ๊ตฌ์กฐ๋ผ๊ณ ๋ณด๋ ๊ฒ ๊ฐ์๋ค.
์ข ๋ ์กฐ์ฌ๋ฅผ ํด๋ณด๋ ํด๋ฆฐ ์ฝ๋์ ๋ฆฌํฉํ ๋ง์ ๋ฐ์ด๋ธ๊ณผ๋ ๊ฐ์ ์ฑ
์ธ Martin Fowler์ ใRefactoringใ์์๋ ์ด ๋ถ๋ถ์ ๋ฐ๋ก ์ธ๊ธํ๊ณ ์์๋ค. ์ฑ
์์๋ nesting๋ ์กฐ๊ฑด๋ฌธ์ ๋ฆฌํฉํ ๋ง ๋์์ด๋ผ๊ณ ๋งํ๋ค. ์ด์ ๊ฐ ๋ญ๊น? ย ์ด๋ฒ ๊ธฐํ์ if
-else
-return
๊ณผ if
-return
-return
์ ์ฐจ์ด๋ฅผ ๋ณด๋ค ์ฒด๊ณ์ ์ผ๋ก ์ ๋ฆฌํด ๋ณด์๋ค.
if
-return
-return
๊ตฌ์กฐ์ if
์ ย ๋ฐ๋ก ์ด๋ฆ๊น์ง ๊ฐ๊ณ ์๋ค๋๊ฑธ ์๊ฒ ๋๋ค. ๋ฐ๋ก "guard clause"๋ผ๋ ๊ฒ์ด๋ค. ์
๋ ฅ๊ฐ์ด ๋ค ์
๋ ฅ๋์ง ์๊ฑฐ๋ ์ ํจํ ์์์ด ์๋๊ฑฐ๋ ํ๋ ์์ธ ์ผ์ด์ค๊ฐ ์ค์ ๋ก ์์ฑํ ํผ์ ์ ์ถํ๋ ์ฃผ์ ์ ๋ก์ง์ ํ์ง ๋ชปํ๋๋ก ๋ง๋ ๋ฌธ์ง๊ธฐ(guard)์ ์ญํ ์ ํ๋ ์ (clause)์ด๋ผ๋ ๊ฒ์ด๋ค. ์ด guard clause๋ฅผ ์ฐ๋ฉด ์ด๋ค ์ ์์ ์ ๋ฆฌํ๊ฑธ๊น?
if-return-return
function doSomething () {
if (!isInvalid) {
return ERROR_MSG
}
return VALUE
}
๐ข ๊ฐ๋ ์ฑ์ด ๋์์ง๋ค: ์์ ๋งํ๋ ๊ฒ์ฒ๋ผ nesting์ ์ค์ฌ์ ๊ฐ๋ ์ฑ์ด ์ข์์ง๋ค
๐ข ํจ์๊ฐ ํ๋ ์ผ์ด ๋ฌด์์ธ์ง ํ์ ํ๊ธฐ ์ฝ๋ค: ย guard clause๋ฅผ ์ฐ๋ฉด ์์ธ์ ๋ง nestingํ๊ณ ์ฃผ์ ์ ํจ์ ๋ณธ์ฒด์ ๋ฐ๋ก ์์ฑํ๊ธฐ๋๋ฌธ์ ํจ์์ ์ญํ ์ ์๊ฐ์ ์ผ๋ก ๋ณด๋ค ์ ๋๋ฌ๋ธ๋ค.
๐ข ์ฝ๋๊ฐ์ ๊ฒฐํฉ๋(coupling)๋ฅผ ์ค์ธ๋ค: if
-return
-return
๊ตฌ์กฐ์์๋ ๋ ์ด์ ์์ธ์ฒ๋ฆฌ๋ฅผ ํ ํ์๊ฐ ์์ด์ก์ ๊ฒฝ์ฐ์ if
์ ๋ง ํต์งธ๋ก ๋ค์ด๋ด๋ฉด ๋๋ค. ๋ฐ๋ฉด ๊ฐ์ ๋ก์ง์ if
-else
-return
๊ตฌ์กฐ๋ก ์์ฑํ์ ๊ฒฝ์ฐ ์์ if
๋ฅผ ์ง์ฐ๋ฉด ๋ค์ else
๋ ๊ฐ์ด ์ง์ฐ๊ณ else
์ ์์ ๋ค์ด์๋ ์ฝ๋๋ค ์ ์ฒด๋ฅผ ๊ดํธ ๋ฐ๊นฅ์ผ๋ก ๊บผ๋ด๋ ๋ฑ ๋ณด๋ค ๋ง์ ์ฝ๋๋ฅผ ๊ณ ์ณ์ผํ๋ค. ์ฝ๋๋ค๊ฐ์ ์์กด์ฑ, ๊ทธ๋ฌ๋๊น ๊ฒฐํฉ๋(coupling)๊ฐ ์๊ธด ๊ฒ์ด๋ค. ์ด๋ฌํ ์์กด์ฑ์ if
-return
-return
๊ตฌ์กฐ์์๋ ์ค์ผ ์ ์๋ค.
if-else-return
function doSomething () {
if (isValid) {
return VALUE
} else {
return ERROR_MSG
}
}
โ ์ฃผ์ ๊ณผ ์์ธ์ ์ ๋ชจ๋ nestingํ๋ฉด ํจ์๊ฐ ์ค์ ๋ก ์ด๋ค ์ผ์ ์ฒ๋ฆฌํ๊ณ ์ ํ๋์ง๊ฐ ๋์ ์ ๋๋ฌ๋์ง ์๋๋ค. ๋๊ฐ์ด ๋ค์ฌ์ฐ๊ธฐ๋ ๋ ์ ์ด ๋
ผ๋ฆฌ์ ์ผ๋ก๋ ๋์ผํ ์์์ ๊ฐ์ง๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๊ธฐ ๋๋ฌธ์ด๋ค. ํ์ง๋ง ์ค์ ๋ก doSomething
ํจ์๊ฐ ํ๊ณ ์ถ์ ์ผ์ VALUE
๋ผ๋ ์ ์๋ฏธํ ๊ฐ์ ๋ฆฌํดํ๋ ๊ฒ์ด์ง ์๋ฌ ๋ฉ์์ง๋ฅผ ๋์ง๋ ๊ฒ์ด ์๋๋ค. ์์ธ์ ๊ณผ ์ฃผ์ ์ ๋ค์ด์ค๋ ์ฝ๋๊ฐ ๋ง์์ง์๋ก, ๊ทธ๋ฆฌ๊ณ ์์ธ์ ๋ด์์ ๋ ์์ธ์ ์ด ์ค์ฒฉ๋ ๊ฒฝ์ฐ ํจ์์ ์ญํ ์ ํ์
ํ๊ธฐ๊ฐ ์ ์ ๋ ์ด๋ ค์์ง๋ค.
โ ์์ธ์ ๊ณผ ์ฃผ์ ์ฌ์ด์ ์ฐ๊ด์ฑ์ ํ์
ํ๊ธฐ ํ๋ค๋ค: if
์ ๊ณผ else
์ ์ ๋
ผ๋ฆฌ์ ์ผ๋ก ์ฐ๊ด๋์ด์๋๋ฐ if
์ ๊ณผ else
์ ๊ฐ๊ฐ์ ๋ง์ ์์ ์ฝ๋๊ฐ ๋ค์ด๊ฐ์์ผ๋ฉด ๋ ๊ฐ์ ๋
ผ๋ฆฌ์ ์ฐ๊ด์ ํ์
ํ๊ธฐ ํ๋ค๊ณ ์ฝ๋ ์์๋๋ฅผ ์๋ค๊ฐ๋ค ํด์ผํ๋ ์ถ๊ฐ์ ์ธ ์๊ณ ๊ฐ ๋ ๋ค.
๐ข ๋ค๋ง Martin Fowler๋ ใRefactoringใ์์ if
-return
-return
๊ตฌ์กฐ์ if
-else
-return
๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๋ ์กฐ๊ฑด๋ฌธ์ ๊ฐ๊ฐ ๋ค๋ฅธ ์๋๋ฅผ ๊ฐ์ง๋ค๊ณ ๋งํ๊ณ ์๋ค. ์ค์ ๋ก if
์ ๊ณผ else
์ด ๋์ผํ ์ค์๋๋ฅผ ๊ฐ์ง๋ค๋ฉด ย if
-else
-return
๊ตฌ์กฐ๋ฅผ ์ฒดํํ ์ ์๋ค๋ ๊ฒ์ด๋ค. ๋ค๋ง ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ์ if
-else
-return
๊ตฌ์กฐ๋ ๋ฆฌํฉํ ๋ง ๋์์ ํด๋นํ๋ค.
Closing
์ ์ด์ ์ ๊ธฐ์ตํด ๋จ๋ค๊ฐ ์ฝ๋ ๋ฆฌ๋ทฐ๋ ์จ๋จน๊ธฐ๋ง ํ๋ฉด ๋๋ค.
References
- "It is more efficient to use if-return-return or if-else-return?", Stack Overflow
- Refactoring: Improving the Design of Existing Code, Edition 2, Fowler, Martin. Addison-Wesley Professional, 2018. 695-706.