Guard Clause란 무엇일까
if/else
분기는 프로그래밍을 처음 배울때 가장 먼저 접하는 컨셉중 하나입니다. 조건 분기가 필요한 부분에서 가장 흔하게 사용되는 statement
이기도 한데요, 이 간단한 if/else
가 복잡해지고 중첩되면 부담이 되고 가독성을 크게 해칠 수 있습니다. 쉽게 복잡해질 수 있는 중첩의 수준, 즉, 코드의 depth
가 깊어지는 것을 막을 수 있는 방법으로 Guard Clause
를 고려해 볼 수 있습니다. 이 Code Clause
를 통해 중첩된 조건문을 평탄화(flattening)시켜 코드의 가독성을 향상시킬 수 있습니다.
일단 Guard가 뭔지 알아보자
“In computer programming, a guard is a boolean expression that must evaluate to true if the program execution is to continue in the branch in question. Regardless of which programming language is used, guard code or a guard clause is a check of integrity preconditions used to avoid errors during execution.” — Wikipedia
쉽게 생각하면, null
체크와 같이 조건분기에서 계속 실행되기 위해 true
여야 하는 boolean expression
을 의미합니다.
Concept
다음과 같은 기존의 코드가 있습니다.
1 | if (guard) { |
이 코드를 not guard
의 조건으로 바꾸고 조기에 return
합니다 (return early). 그 다음, 기존의 guard
조건을 가진 분기의 코드 블락을 아래와 같이 not guard
이후에 작성하면 됩니다. 이제 위의 분기 코드를 아래와 같이 표현할 수 있습니다.
1 | if(not guard) { |
여기까지만 보면 오히려 멀쩡한 조건문에 not
을 씌워 가독성을 해치는 것으로 보일 수 있습니다. 하지만 실제로 중첩 조건문에서 적용하여 중첩 조건문을 평탄화 하여 코드의 깊이를 줄이는 것을 보여드리겠습니다.
중첩 조건문에 적용
예시로 아래와 같이 token
을 인증하는 가상의 코드가 있다고 했을 때, user
가 존재 하는지 확인하고 해당 token
을 가져와 존재하는지 확인한 후, token
의 purpose
가 reset
인지를 확인해서 이경우 true
를 반환합니다.
1 | public async verifyToken(email: string, token: string, purpose: string) { |
이런 간단한 코드의 경우에도 이미 중첩 조건문이 3번 중첩됩니다. 코드가 더 복잡해지면 쉽게 코드의 depth
가 깊어져 가독성을 해치고 코드를 이해하는데 어려움을 겪게 됩니다. 이 코드에서는 if(user)
, if(token)
그리고 if(token.purpose === 'reset')
가 Guard
가 됩니다.
Guard Clause 적용
앞서 말한대로 코드를 refactor
해보도록 하겠습니다. Guard
조건들을 Not Guard
로 바꾸고 early return
해줍니다.
1 | public async verifyToken(email: string, token: string, purpose: string) { |
Guard Clause
를 토대로 refactor
를 마친 코드를 보면 중첩된 조건문이 사라진건 알 수 있습니다. 이렇게 복잡한 조건문을 쉽고 가독성 높은 코드로 풀어낼 수 있는 Guard Clause
에 대해 알아 봤습니다.