들어가며
오늘 오랜만에 소마 연수 센터에 가서 '클린 코드 책만 사고 아직 안 읽어보신 분을 위한 특강'이라는 클린 코드 책 리뷰 멘토링을 들었다.
멘토링에서는 클린 코드의 1~3장에 대해 멘토님의 특강을 듣는 방식으로 진행되었다.
멘토링을 들으며 소마에서 진행하는 프로젝트에 대해 되돌아볼 수 있었고, 평소 코드를 작성하며 궁금했지만 사소한 질문들에 대해 물어보고 조언을 구할 수 있어 뜻 깊은 시간이었다.
이번 포스트에서는 멘토링에서 했던 질의응답을 복기하고, 클린 코드에 대한 생각을 정리하고자 한다.
postService.save() vs postService.savePost()?
Spring boot에서 클래스를 생성할 때 PostController, PostService 등 ... 해당 도메인을 앞에 명시해주는 방식으로 클래스명을 짓게 된다.
그리고 메서드를 호출할 때는 점 연산자(.)를 사용하기 때문에 save라고 메서드명을 지어도 앞에 있는 객체명을 보고 어떤 주체(ex. Post)에 대한 행위(ex. save)인지 의도가 드러난다고 생각했다.
하지만 다른 관점으로 봤을 때, 메서드 호출부가 아닌 구현부에서 봤을 때는 클래스명을 확인하기 전에는 의도가 불명확하지 않을까?
멘토님은 '검색할 때 해당 코드를 찾기 쉬운지'에 대해 이야기해주시며 IDE의 성능과도 연관되어 있다고 말해주셨다.
개발자들은 코드 작성을 마친 후에도 필요한 코드를 찾기 위해 검색하는 일이 자주 있다. 필요한 코드를 검색할 때 잘 찾아지는 것도 중요한 고려사항이다.
IDE마다 검색 결과가 출력되는 방식이 다르기 때문에 IDE의 성능과도 연관이 있다고 하신 것이다.
IntelliJ에서는 save로 메서드명을 작성하여도 어떤 클래스에 들어있는지 우측에 표시되기 때문에, 저 정도면 검색을 할 때 불편하지 않다고 생각한다.
더불어 요즘 Spring 개발자들은 대부분 IntelliJ를 사용하므로 IDE의 차이에 대해서는 고려하지 않아도 될 것 같다!
결론
메서드명에 직접적으로 도메인을 적어주지 않아도 의도를 파악하는 것이 가능하고, 검색에도 불편하지 않기 때문에 메서드명에 도메인을 포함하지 않아도 된다.
참고로 포스트에서 이어질 결론을 절대 클린 코드의 정답이 아니다. 코드 작성에 대한 나의 생각을 한 줄로 정리한 것이기 때문에 '얘는 이렇게 생각하는구나~' 정도로만 참고해줬으면 좋겠다.
테스트 코드에서의 변수명
클린 코드의 2장 '의미 있는 이름'에서는 변수, 메서드, 클래스의 이름을 명명하는 방법에 대해 소개된다.
책에서는 변수나 메서드의 이름에 숫자가 들어가지 않는 것을 권장한다.
멘토링을 들으며 테스트 코드를 적을 때 member1, member2처럼 변수명에 숫자를 붙였던 일이 기억 났다.
로직이 중요한 서비스 코드와 달리 테스트 코드는 스토리(ex. 게시글이 삭제되면 게시글 목록에서 해당 게시글이 조회되지 않아야 한다.)가 중요하고, 테스트 코드에는 로직이 들어가면 안된다고 생각한다.
서비스 코드에서는 의미 있는 변수명이 로직을 정확히 이해하는 것과 깊은 연관이 있기 때문에 중요하지만, 테스트 코드에서는 맥락이 이해가 된다면 변수명은 덜 중요하다고 생각했다.
이 질문에 대해서 멘토님은 '테스트 코드에서는 예외가 적용될 때가 많다. 하지만 책에서는 테스트 코드에서도 동일한 규칙(의미가 명확한 명명)을 적용할 것을 권장한다'라고 답해주셨다.
예외가 적용된다는 것을 보아 서비스 코드와 테스트 코드는 다른 목적을 지니고 있기 때문에, 각 코드에서의 클린 코드에 대한 기준도 다르다는 점이 나의 생각과 어느 정도 부합한다고 생각한다.
결론
변수명이 테스트의 스토리 라인을 파악하는데 영향을 미친다면, 의미 있게 지어주도록 노력하자.
하지만 스토리에서 비중 있는 역할이 아니라면 변수명에 대한 압박을 잠시 내려놔도 될 것 같다.
코딩 컨벤션, 어디까지 통일해야 할까?
프로젝트를 시작할 때는 코드 리뷰를 진행하지 않다가 중간에 코드 리뷰를 도입하니 생각보다 팀원과 코드 스타일이 다른 부분이 있다는 것을 알 수 있었다.
코드 리뷰를 진행하며 다른 점을 찾고 컨벤션에 대한 규칙을 조금씩 추가해나갔다. 그 중에서는 가독성을 고려했을 때 통일하는 것이 중요한 부분도 있었고, 개인 취향에 따라 달라질 수 있는 사소한 부분들도 있었다.
후자와 같은 부분에 대해 컨벤션을 정할 때는 두 사람의 코드 모두 논리적으로 문제가 없기 때문에 어떤걸 선택해야 할지 애매했고, 이런 상황에 대해 멘토님께 질문드렸다.
멘토님은 코드 컨벤션에는 mandatory(필수적)인 것이 있고, 선택적으로 해도 되는 것이 있다고 말해주셨다.
즉, 모든 코드 작성 스타일에 대해 컨벤션을 정할 필요는 없다는 의미이다. 개발할 때 숨통이 막히면 안된다고 함께 말해주셨다.
중요도가 높지 않은 부분에 대해서는 자유롭게 작성 가능하도록 하는 것이 좋다.
Like ... 책상 배치에 규칙은 있지만 ... 자세히 보면 각이 완벽하지 않은 나의 책상처럼 ....
나는 ISTJ라서 최대한 컨벤션을 꼼꼼하게 정하고 규칙성 있는 코드를 선호하는 스타일이다. 그렇기 때문에 가능한 모든 부분에 대해 컨벤션을 만들고자 했던 것 같다. 나의 장점이라고 생각한 부분이 다른 사람에게는 부담이 될 수 있었겠다고 느끼며, 클린 코드는 단순히 '개발'에서 중요한 것이 아니라 협업하는 동료를 향한 '배려'임을 깨달았다.
결론
1. 모든 코드 스타일에 대해 컨벤션을 정하지 않아도 된다.
2. 클린 코드는 동료를 향한 배려이다.
클린 코드는 만능이 아니다
멘토링 마지막에 아래 영상과 블로그 글을 소개해주셨다.
잘가, 클린 코드
클린 코드를 배우되, 얽매이지는 마세요.
overreacted.io
클린 코드 책이 유명해지면서 '클린 코드 === 곧 해당 도서에서 말하는 내용'이라고 생각하게 되는 경우가 있다.
클린 코드 책에 나온 내용을 좋은 인사이트로 수용하되, 바이블처럼 여기지는 말자.
클린 코드는 업무 효율을 높여주는 중요한 수단이다. 하지만 가독성을 높이는 행위가 때로는 프로그램의 성능을 저하시킬 때가 있다.
ex) Java에서 Stream을 통해 일관성 있게 코드를 작성할 수 있지만, for문을 사용했을 때보다 오버헤드가 발생하며 정교한 최적화를 수행하기 어렵다.
성능, 빠른 속도가 fatal하게 중요한 프로그램에서는 클린 코드보다는 조금이라도 성능이 더 좋은 코드가 좋은 코드일 것이다.
클린 코드는 나를 좋은 개발자를 이루는 여러 요소 중 하나임이 분명하다.
하지만 장점만 존재하는 것은 없다. 클린 코드를 맹목적으로 찬양하지 않도록 주의하자!