옛날에 샀던 책이지만 최근에 클린 코드에 대한 욕구가 커져서 책장에 묵혀놨던 책을 다시 꺼내보게 되었다.
앞으로 이 책을 정독하면서 인상깊었던 부분을 정리하고 나만의 코드 철학을 만들어 보고자 한다. 그리고 철학을 정하는 것만으로는 의미가 없기 때문에 항상 그 부분을 생각하면서 코딩을 하려고 노력할 것이다.
1. 깨끗한 코드란 무엇일까
이 책에서는 다양한 대가들의 '좋은 코드'의 정의를 다룬다. 이들을 읽어보고 내가 내린 정의는 다음과 같다.
'중복이 없고, 기능을 모두 구현하면서도 쉽게 읽히는 코드' 를 좋은 코드라고 정의할 수 있을 것 같다.
사실 이들이 내린 정의 모두 프로그래머라면 한번쯤은 생각했던 포인트가 아닐까 싶다.
누구나 좋은 코드, 깔끔한 코드, 남들이 이해하기 쉬운 코드를 짜려고 노력한 경험이 있지 않은가?
하지만 일정에 밀려서, 귀찮아서 '구현'만 되는 쉬운 길을 택하게 되고, 다른 사람이 업무를 맡게 되거나 심지어는 기존에 개발하던 사람조차도 기존 코드를 이해하는데 시간을 많이 소비하게 된다.
2. 이름 짓기
비영어권 프로그래머로서 이름 짓기(변수명, 파일명, 함수명 등)는 생각보다 오랜 시간을 소비하는 작업이다.
같은 뜻을 가진다고 생각하는 단어들 사이에도 미묘한 뉘앙스 차이가 존재하고, 프로그래밍에 일반적으로 사용되는 동사나 명사가 존재하기 때문에 이들을 고려하면서 이름 짓는 것은 확실히 쉬운 일은 아니다.
책의 서두에서도 꼭 모든 조언을 받아들일 필요는 없다고 하기도 했거니와 저자의 모든 의견이 나와 일치하지는 않기 때문에 많은 내용 중에서 내가 공감하는 내용만 받아들이려고 한다.
의도를 분명히 밝혀라
자바스크립트에서 map 함수를 사용할 때
.map(el => el.x)
과 같은 표현을 많이 사용하곤 했는데, el 역시 의미를 가지는 변수명으로 바꿔야 한다는 것이다.
이 부분은 귀찮다는 이유로 쉽게 의미없는 변수를 사용하기가 쉽기 때문에 항상 신경쓰고 있어야 하는 부분 같다.
또한, 불필요한 의도(c++에서 멤버 변수를 정의할 때 m_를 앞에 붙이기 등)를 드러내는 부분은 과감히 제거해야 한다.
이전 코딩 스타일에는 맞을지 몰라도 현대의 코딩 스타일에는 맞지 않는 부분이다.
그리고 클래스명이나 객체명에는 명사 및 명사구, 메소드명이나 함수명에는 동사 및 동사구를 사용하도록 하자.
상수를 적극 활용하자
숫자나 문자열을 직접 사용하기보다는 이를 constant로 정의해 놓고, constant를 사용하는 습관을 들여야 한다.
상수를 사용한다면 해당 상숫값을 변경할 일이 있을 때검색 및 변경이 편리하고, 코드를 읽는 사람이 의미를 유추하기도 쉬워진다.
한 개념에 한 단어를 사용하자
사실 이 부분은 혼자 개발하는 프로젝트가 아닌, 다른 개발자와의 협업이 있을 때 많이 발생하는 문제이다.
값을 가져오는 메소드에서 fetch, get, retrieve 등 다양한 단어를 혼재한 채로 사용하는 경우가 많다.
이 부분은 명확한 해답이 없기 때문에 같은 프로젝트를 진행하는 팀원들 사이에 합의가 있어야 한다.
만약 이 부분이 해결되지 않는다면 비슷한 기능을 하는 메소드를 수정할 때 fetch, get, retrieve 각각 모두 검색한 후 수정하는 경우가 생길 수 있다.
이상적인 해결방법은 개발에 사용되는 용어가 정리된 문서를 관리하고, 개발할 때 항상 그 매뉴얼을 숙지한 채로 코딩하는 방법이 있지만, 모든 용어에 대해서 문서를 유지할 수 없기 때문에 현실적이지 않다.
아마 전임자가 작성한 코드를 보고 용어를 선택한 후에 나중에 그 맥락에 맞지 않는 단어를 보았을 때 '즉시' 수정하는 방법이 현실적일 수 있겠다.
3. 함수
이름 짓기보다 더 고민이 많은 파트이다.
이름 짓기의 경우 해결이 명쾌한 경우가 많다.
어찌되었든 '이름'을 적당히 변경하면 되므로.
하지만 함수의 경우, 어느 정도 길이까지를 한 함수로 보고, 어느 정도까지 추상화를 해야 하는지는 사람마다 의견이 분분하다.
심지어는 이 책의 저자가 best practice로 제공한 코드도 내 마음에는 들지 않을 정도이다.
그래서 책의 내용을 바탕으로 규칙을 정해 보았다.
한 가지를 '잘' 해라
이 파트에서 저자가 지속적으로 강조한 개념으로 상당히 모호한 개념이기도 하다.
'한 가지'를 어떻게 정의하느냐에 따라 목표한 수준의 코드가 될 수도, 아닐 수도 있다.
나는 저자와 마찬가지로 섹션으로 나누어질 수 있다면 두 가지 이상의 작업을 하는 것으로 정의했다.
인수는 적을 수록 좋다
읽으면서 굉장히 공감 많이 했던 부분이다.
keyword 인수가 아닌 이상, 인수 순서를 헷갈려서 함수 실행 결과를 잘못 리턴받은 경우도 허다하고, 무엇보다도 인수가 많아지면 자연스럽게 함수의 복잡도 또한 기하급수적으로 증가하는 경우가 많기 때문이다.
항상 인수의 개수를 더 줄일 수 없을까 고민하다 보면 함수의 추상화 수준도 고민할 수 있고, 그러다 보면 함수의 대원칙 '한 가지를 잘 해라'라는 것을 한 번 더 고민해 볼 수 있지 않을까 생각한다.
플래그 인수(ex: isDir 등) 의 경우 저자는 가급적 삼가는 편이 좋다고 주장하는데, 나는 이 주장에 일부만 동의한다.
지나치게 많이 사용하지만 않는다면 플래그 인수 역시 유용하고, 플래그 인수가 있다고 해서 '냄새나는' 코드가 되지는 않는 것 같다.
가급적 사용을 줄이되, 필요한 경우는 플래그 인수 역시 사용하는 편이 오히려 좋을 수 있다고 생각한다.
인수가 많이 필요한 경우는 인수들을 묶어서 class로 만들고 객체를 인수로 보내는 방식은 실무에서 사용하면 좋은 방식 같다.
한 클래스로 묶게 되면 좀 더 의미가 분명해지고, 읽기도 편해지는 장점이 존재한다.
오류코드보다는 exception을 발생시켜라
사실 이전에는 생각하지 못했던 개념이지만, 곰곰히 곱씹어보니 일리가 있는 주장 같다.
오류 코드 형태로 처리하는 경우는 old-fashion의 c 코드에서 기인한게 아닐까 생각이 든다.
오류 코드들을 exception 형태로 정의하고, try catch로 해당 오류를 처리하는 방식으로 변경하면 함수의 대원칙 '한 가지를 잘 해라'에도 들어맞지 않을까 생각이 든다.
'better code' 카테고리의 다른 글
[TIL] copy-on-write 방법론 - js에서 퍼포먼스 테스트 (0) | 2023.04.22 |
---|---|
Clean Code (5/n) (0) | 2022.02.21 |
Clean Code (4/n) (0) | 2022.02.16 |
Clean Code (3/n) (0) | 2022.02.11 |
Clean Code (2/n) (0) | 2022.02.07 |