국내에서는 "읽기 좋은 코드가 좋은 코드다"라는 제목으로 번역된 책을 소개합니다.
로버트 마틴(밥 아저씨)가 지은 클린 코드 보다 유명한 책은 아닙니다만, 코드의 기본기를 다지는데 도움을 줄수 있는 책이라 생각됩니다.
이 책을 보다가 당황스럽지만 재밌는 구절이 있어서 소개해 봅니다.
Part II Simplifying Loops and Logic 에 있는 구절입니다.
if (user_result == SUCCESS) {
if (permission_result != SUCCESS) {
reply.WriteErrors("error reading permissions");
reply.Done();
return;
}
reply.WriteErrors("");
} else {
reply.WriteErrors(user_result);
}
reply.Done();
If 문의 중첩에 대해서 이야기하고 있습니다. 이 코드는 원래 아래 코드에서 시작되었을 것입니다.
웹 서비스로 사용자 인증을 하다 보면 자주 만나게 되는 코드입니다. user_result 는 아마도 사용자 인증이 성공되었는지를 가지고 있는 듯 합니다. 성공했으면, 에러를 뿌리지 않고, 그렇지 않다면 에러를 뿌린다. 그리고 reply 를 끝낸다. 이정도로 해석되네요.
if (user_result == SUCCESS) {
reply.WriteErrors("");
} else {
reply.WriteErrors(user_result);
}
reply.Done();
이후에 사용자 이용권한 관련 내용이 추가되었을 것입니다. (permission_result)
아 user_result 가 성공한 경우에만 permission_result 가 의미가 있군...
그렇다면 if 문의 전반부에 이 코드를 넣으면 되겠군...
이렇게 생각하는 것은 너무나 당연한 일이라 바로 이를 코딩합니다.
그 결과 중첩된(Nested) IF 문이 탄생하였습니다.
이 책에서는 다음과 같이 코드를 간략화 하였습니다. 간략화라는 뜻은 Nested 를 없앴다는 뜻입니다.
if (user_result != SUCCESS) {
reply.WriteErrors(user_result);
reply.Done();
return;
}
if (permission_result != SUCCESS) {
reply.WriteErrors(permission_result);
reply.Done();
return;
}
reply.WriteErrors("");
reply.Done();
이전보다 나은 코드가 되었을까요?
- 로그인이 성공적이지 않으면, 에러를 출력하고 끝
- 이후에는 무조건 로그인 성공인 경우만 들어오므로 이제 권한을 확인해서 권한이 성공적이지 않으면 에러를 출력하고 끝
- 이제는 로그인도 성공, 권한도 성공
이러한 의식의 흐름이 따라오게 되는 읽기 좋은 코드가 되었네요.
이 책에서는 당황스럽게도 이렇게 바꾸는 방법에 대해서 설명하고 있습니다.
KEY IDEA
Look at your code from a fresh perspective when you’re making changes. Step back and look at it as a whole.
코드를 바꾸는 경우 새로운 관점에서 바라보라, 뒤로 물러서서 전체를 바라보라.
예전에도 이런 코드에 대한 개선(리팩토링)을 설명한적이 있었는데, 그 당시에는
if (condition) A and B 가 있으면 A B 를 바꾸면 좋을지 보고
Early return on exception 방식을 사용해라
이런 구차한 설명을 했던 것 같습니다. 답을 보고 과정을 설명하는 것이라 구차하다고 한 것입니다.
이 책에서는 한마디 테크닉(?)도 없이 그저 "뒤에서 전체를 바라보라" 라는 말로 방법을 설명하고 있었고, 이 당황스러운 말에 큰 감동을 받아 지금도 모니터를 멀찌감치 두고 코딩을 하고 있습니다.
코드는 잘 짜야하고 잘 짜지 않은 코드는 1주일 내에 쓰레기가 될 확률이 높습니다.
오늘도 이러한 일이 발생하였고, 예전 생각이나서 글을 한번 올려봅니다.