※ 대부분에 언어에 해당될 수 있는 내용이지만, javascipt 언어에 가장 적합한 글입니다.
0. 깊이가 얕은 Early Return 방법
말 그대로 일찍이 RETURN 하여 함수를 빠져나오는 것이다. 바로 코드를 보자.
const isNumber = v => /^(\s|\d)+$/.test(v);
//<Base Code>
function getBoardByRegisterId(registerId) {
if (registerId.length >= 4) {
if (isNumber(registerId)) {
const data = [];
// 20 Line ...
return data;
} else {
alert('아이디는 숫자만 유효합니다.');
}
} else {
alert('아이디는 4자 이상 필요합니다.');
}
}
//<Early Return - is Good?>
function getBoardByRegisterId(registerId) {
if (registerId.length < 4) {
alert('아이디는 4자 이상 필요합니다.');
return;
}
if (!isNumber(registerId)) {
alert('아이디는 숫자만 유효합니다.');
return;
}
const data = [];
// 20 Line ...
return data;
}
<Base Code>를 보면 조건문(if) 마다 들여쓰기(Indent)되어 가독성을 해치는 깊이(Depth)가 생긴다. 조건의 깊이(Depth)가 깊어지면 어떠한 조건일 때 실행되는 로직인지 파악하기 어렵다. 특히, 메인 로직과 서브 로직(예. 자잘한 유효성 로직 등)을 함께 가지는 조건문을 쉽게 만날 수 있는데 주요 로직 부분의 라인 수가 길어지면 서브 로직 부분이 매우 하단에 위치하게 되어 읽기 어려워진다.
어떤 이들은 취향 차이라고 말하는 분들도 있지만, 좋은 코딩을 논할때 항상 나오는 키워드이자, 실제로 우아한형제들(배달의민족)에서 지원하는 교육인 '우아한테크코스' 미션 중 'switch/case 와 else 예약어를 쓰지 않고 코드를 작성한다.'라는 제한 조건으로 <Early Return> 방법을 권장하는 만큼 긍정적으로 보는 방법 중 하나로 보인다.
1. RETURN 문 을 활용하여 한 줄(Single Line)로 만들기
<Early Return> 방법을 쓴다고 해서 기존보다 줄(Line) 수가 줄지는 않는다. 분명, 줄(Line) 수가 적으면 가독성의 이점이 있다. RETURN 문을 잘 활용하면 줄(Line) 수를 줄일 수도 있다. 그 예시를 보자!
(IF 문에 명확하게 중괄호({})를 쓰는 것도 좋은 방법 중 하나이기에 이 방법은 명확하게 개인의 취향이다.)
//<Early Return Ver 2 - is Good??>
function getBoardByRegisterId(registerId) {
if (registerId.length < 4) return alert('아이디는 4자 이상 필요합니다.');
if (!isNumber(registerId)) return alert('아이디는 숫자만 유효합니다.');
const data = [];
// 20 Line ...
return data;
}
RETURN 문은 RETURN 직후에 오는 값을 함수의 반환 값으로 결정하고 함수를 EXIT 한다.
위와 같이 작성하면, alert()을 실행 후 값을 가져와 함수의 반환 값으로 결정하는데,
이때, alert이 실행된다. 어떤 값이 반환될까?
alert 또한 함수이기때문에 무언가를 반환할 텐데 그것이 'undefined'이고 위 함수의 반환 값으로도 결정이 되기에 'undefined'가 최종 반환된다. 'getBoardByRegisterId' 라는 함수 자체가 data를 반환하는 값인데, undefined로 반환이 될 수도 있는 상황이기 때문에 위와 같이 SINGLE LINE RETURN을 활용할 경우 어떠한 값이 반환되는지를 잘 컨트롤하여 작성해야 한다. 확실히 가독성은 높아진다. 허나, Return Type 이 불분명 해진다는 단점은 있을 수 있어 충분히 고려해보아야 한다.
2. 조건문이 보일때마다 <Early Return>을 적용하는 것이 맞을까?
좀 더 복잡한 코드를 보자.
//<Base Code>
function executeUserLogic(paymentType, age, country) {
if (paymentType === "PAID") {
if (age > 20) {
if (country === "korean") {
// 20 Line ...
logic1();
} else {
// 20 Line ...
logic2();
}
} else {
// 20 Line ...
logic3();
}
} else {
//pass
}
}
//<Early Return - is Good?>
function executeUserLogic(paymentType, age, country) {
if (paymentType !== "PAID") return;
if (age <= 20) {
// 20 Line ...
logic3();
return;
}
if (country !== "korean") {
// 20 Line ...
logic2();
return;
}
// 20 Line ...
logic1();
}
각 로직의 영역마다 20줄(Line)을 차지한다면 이 함수 자체는 굉장히 거대한 함수일 가능성이 높다. 또한, 3개의 인풋 변수에 의한 다양한 케이스를 다루면서 동시에 로직 하나하나 중요도가 높다면 매우 복잡해 보일 수도 있다. 그 거대하고 복잡한 함수를 <Early Return>을 통해 개선했다고 쳐도 결국 이해하기 어려운 건 매 한 가지일 수도 있다.
명시적이지 않다고 느낄 수 있는 지점도 있는데, 실제로 위 함수에서 [Logic1] 함수는 ['유료' and '성인' and '한국' 유저]들에게 실행시키고 싶은 것인데, <Early Return> 방법으로 개선되면 어떠한 조건들로 인하여 Logic1 함수가 실행되는지 위의 조건을 잘 훑어봐야한다. 이럴 땐 <Early Return>이 최선이 아닐 수 있고 다른 방법을 시도하거나 다른 방법과 함께 <Early Return>을 시도해야 한다.
이 지점부터는 <Early Return>이 사람마다 취향차이 일수도 있다는 생각이 확 들지만, 그럼에도 불구하고 나 같은 경우에는 <Early Return>은 무조건 적용해보고 또 다른 방법을 더해볼 것 같다.
위 케이스를 좀 더 좋게 만들기 위해서는 다른 방법들을 좀 더 살펴본 뒤 해결해보면 좋을 것 같다.
3. <Early Return> 관련 읽어보면 좋은 글
https://medium.com/swlh/return-early-pattern-3d18a41bba8
간단하게 요약해보기!
<Early Return> 패턴은 코드가 흐름대로 읽히고(read linearly), 긍정적인 흐름으로 작동한다.(happy path)
200줄 이상의 함수에서 return 문을 무작위로 많이 쓰면(Multiple exit points) 이해가 어렵다는 비판적인 시각도 있다. (개인적으로는 200줄 이상 자체가 문제가 아닐까 싶다)
결론은 <Early Return>은 훌륭한 방법 중 하나이고 매번 적용해야 한다는 의미는 아니다.
'Deep Dive Series > Good Condition' 카테고리의 다른 글
[좋은 조건문 작성하기 4] JSON 객체를 활용한 조건문 형태 (0) | 2022.02.20 |
---|---|
[좋은 조건문 작성하기 3] 애매한 조건문은 팀원들과 생각 나누기 (0) | 2022.01.08 |
[좋은 조건문 작성하기 2] Switch/Case 톺아보기 (4) | 2021.12.17 |
[좋은 조건문 작성하기 0] 왜 좋은 조건문을 작성해야 할까? (0) | 2021.12.02 |