※ 대부분에 언어에 해당될 수 있는 내용이지만, javascipt 언어에 가장 적합한 글입니다.
복잡한 조건문을 작성하다보면, 무언가 잘못 분기하고 있다고 느낄 때가 있다.
이 부분은 애매하지만 매우 중요한 부분이라 생각되어 어떻게든 글로 풀어써보려고 한다.
정답이 있는 문제라기보단 앞서,
왜 좋은 조건문(IF) 을 작성해야할까? 라는 질문에 나는
'서로의 조건 로직을 잘 이해해 서비스를 잘 디벨롭하기 위해서'라고 답하고 싶다.
라고 포스팅했기에, 아래의 시나리오를 팀원들과 같이 읽어보며 좋은 조건문에 대해서 고민해보면 좋을 것 같다.
상황1 . 과일의 이름에 따라 적용가능한 색깔들(배열)을 가져오는 함수를 만드려는데 조건문을 어떻게 만들지 고민이다.
function availableColorsByFruit1(fruitName) {
switch (fruitName) {
case 'apple' :
return ['green'];
case 'tomato' :
return ['green', 'yellow'];
default :
return [];
}
}
function availableColorsByFruit2(fruitName) {
const colors = [];
if (['apple', 'tomato'].includes(fruitName)) {
colors.push('green');
}
if (fruitName === 'tomato') {
colors.push('yellow');
}
return colors;
}
지극히 주관적인 의견으론 1번이 좋다고 느꼈다.
중복되는 로직이 많더라도 조건식이 간단할 수록 가독성이 좋다고 느끼기 때문이다.
상황2. 위에 만든 함수의 조건이 많이 추가 되면서 1번 방법이 맞는지 고민된다.
function availableColorsByFruit1(fruitName) {
switch (fruitName) {
case 'kiwi' :
case 'tomato' :
return ['yellow', 'green'];
case 'apple' :
case 'melon' :
case 'watermelon' :
return ['green'];
case 'banana' :
case 'pear' :
case 'lemon' :
return ['yellow']
default :
return [];
}
}
function availableColorsByFruit2(fruitName) {
const colors = [];
if (['kiwi', 'tomato', 'apple', 'melon', 'watermelon'].includes(fruitName)) {
colors.push('green');
}
if (['kiwi', 'tomato', 'banana', 'pear', 'lemon'].includes(fruitName)) {
colors.push('yellow');
}
return colors;
}
1번의 조건문은 상하로 길고, 2번의 조건문은 좌우로 길다. 단순히 상하, 좌우가 길어진다는 취향에 의해 선택할 수는 없다.
1번의 조건문은 조건식은 가볍지만 중복된 로직이 존재하고, 2번의 조건문은 조건식은 무겁지만 중복된 로직이 없다.
'yellow', 'green' 외 색이 추가된다고 하면 어떤 방식이 더 가독성이 높을지 고려해보지만 생각처럼 간단한 문제는 아니다.
상황3. 단순 문자 배열 리턴하는 함수에서 색칠 이벤트를 가지는 함수로 변경되었다.
function paintColorsByFruit1(fruitName) {
switch (fruitName) {
case 'kiwi' :
case 'tomato' :
paintYellowColor();
paintGreenColor();
break;
case 'apple' :
case 'melon' :
case 'watermelon' :
paintGreenColor();
break;
case 'banana' :
case 'pear' :
case 'lemon' :
paintYellowColor();
break;
default :
break;
}
}
function paintColorsByFruit2(fruitName) {
if (['kiwi', 'tomato', 'apple', 'melon', 'watermelon'].includes(fruitName)) {
paintGreenColor();
}
if (['kiwi', 'tomato', 'banana', 'pear', 'lemon'].includes(fruitName)) {
paintYellowColor();
}
}
함수로 바꾸자 조건식이 복잡하더라도 중복된 함수를 써서는 안 될 것 같은 느낌이 든다.
그리고 함수를 중복해서 쓰지 않으면 더 개선할 수 있는 여지가 있어 보인다.
(명확하게 여기서 말하는 중복된 함수는 중복 실행이 아닌 중복 선언일때에 한하여 말한다.)
상황4. 함수를 분리하여 좀 더 보기 좋게 리팩토링 가능해보여 이것 저것 시도해본다.
function paintColorsByFruit1(fruitName) {
paintGreen(fruitName);
paintYellow(fruitName);
}
function paintGreen(fruitName) {
if (['kiwi', 'tomato', 'apple', 'melon', 'watermelon'].includes(fruitName)) {
paintGreenColor();
}
}
function paintYellow(fruitName) {
if (['kiwi', 'tomato', 'banana', 'pear', 'lemon'].includes(fruitName)) {
paintYellowColor();
}
}
function paintColorsByFruit2(fruitName) {
isGreen(fruitName) && paintGreenColor();
isYellow(fruitName) && paintYellowColor();
}
function isGreen(fruitName) {
return (['kiwi', 'tomato', 'apple', 'melon', 'watermelon'].includes(fruitName));
}
function isYellow(fruitName) {
return (['kiwi', 'tomato', 'banana', 'pear', 'lemon'].includes(fruitName));
}
확실한 것은 두 가지 조건문 모두 메인 함수는 좀 더 읽힌다는 점이다.
상황5. 갑자기 새로운 로직을 누군가가 추가했다.
function paintColorsByFruit2(fruitName) {
if(fruitName === 'grape'){
paintPurpleColor();
paintRedColor();
paintGreenColor();
return;
}
isGreen(fruitName) && paintGreenColor();
isYellow(fruitName) && paintYellowColor();
}
function isGreen(fruitName) {
return (['kiwi', 'tomato', 'apple', 'melon', 'watermelon'].includes(fruitName));
}
function isYellow(fruitName) {
return (['kiwi', 'tomato', 'banana', 'pear', 'lemon'].includes(fruitName));
}
이때 코드리뷰를 한다면, isPurple, isRed 함수를 만들어야한다고 이야기해야할까?
이게 더 맞는 방법이니까 수정해야한다고 말해야 할까? 아니면 이게 우리의 방법이니까 수정해야한다고 말해야할까?
과연 설득이 가능한 문제일까? 아니면 그렇게 중요하지 않은 부분일까?
간단해보이지만 조건문은 정말 쉽지 않다.
가독성을 높인다고 지나치게 리팩토링했다가 팀원들의 가독성을 헤칠 수 있다.
어쩌면 조금 중복되더라도 충분히 풀어써놓은 조건문이 모두가 이해하기 쉬운 조건문일 수 있다.
정답은 이 글을 보는 팀원들에게 있기에 충분히 토의해보고 좋은 방법을 찾으면 좋겠다.
'Deep Dive Series > Good Condition' 카테고리의 다른 글
[좋은 조건문 작성하기 4] JSON 객체를 활용한 조건문 형태 (0) | 2022.02.20 |
---|---|
[좋은 조건문 작성하기 2] Switch/Case 톺아보기 (4) | 2021.12.17 |
[좋은 조건문 작성하기 1] Early Return은 깊이가 얕아서 좋다! (0) | 2021.12.05 |
[좋은 조건문 작성하기 0] 왜 좋은 조건문을 작성해야 할까? (0) | 2021.12.02 |