NOTE: 이 포스트는 클린코드 - 좋은 코드에 대한 ‘클린코드’ 역자의 생각들 을 보고 정리한 포스트 입니다.
Q & A 위주의 중요한 점 정리
Q. 코드 리뷰 문화 정착을 위한 방법
A.
- 애드혹 리뷰부터!
- 코드리뷰의 단계
- 코드 리뷰 요청자가 ‘어떤 관점’에서 봐달라는 요청이 존재하는 일반 리뷰 방법들과는 달리 애드혹 리뷰는 가볍게 이야기하면서 리뷰하는 방식
- 시니어 개발자 또는 조직장님과 함께하는 애드혹 리뷰가 도움이 많이 됨
Q. 다른 사람의 리뷰를 받을 수 없는 상황일 때, 스스로 좋은 코드를 개발하는 방법
A.
- 코드를 타인에게 설명한다는 느낌으로 접근하기
- 타인의 코드를 많이 보기
Q. 리팩토링의 핵심은?
A.
- 리팩터링은 밖으로 드러나는 동작은 그대로 유지한 채 내부 구조를 변경함으로써 이미 존재하는 코드를 재구성하는 체계적인 기법 by 마틴 파울러
- 체계적인 것이 핵심 -> 리팩터링을 하기 전 범위나 목표에 대한 생각을 하고 미리 티켓을 끊고 작업을 시작할 수 있도록하는것이 좋을 것 같음
Q. 커밋할 때 빌드에 상관없이 모두 나누어야 하는건지?
A.
- 커밋은 논리적인 단위로 모두 나누어야 함
- 어떤 부분에 대한 커밋인지 명확하게 기재해야 함
- 단, 커밋을 통해 빌드가 깨지면 안되며 개별 커밋이 단위 테스트를 깨면 안됨
- 일시적으로 프로그램이 돌아가지 않을 수는 있지만 최소 단위 테스트가 돌아가지 않으면 안됨
- 보통 하나의 커밋 당 2시간 이내의 작업 단위로 나누는 것을 추천(절대적으로 시간적으로 들어가는 비용이 아닌 충분히 한번에 이해할 수 있는 작은 작업단위 정도로 이해하면 됨)
Q. 클래스를 설계하려면?
A.
- 명사와 동사의 구분
- 명사는 대부분 클래스
- 동사는 대부분 메소드
- 주의할 점은 동사 하나가 하나의 메소드와 반드시 1:1로 연결되는것은 아님
- 여러개의 메소드로 쪼개질 수 있음
- 하나의 클래스를 만들었을 때, 그 안의 행위를 어떻게 메소드로 구현할 것인지를 먼저 고민한 후 각각의 클래스를 어떻게 상호작용 하게 할 것인지를 고민하자
- 클래스가 상호작용할 때 시간이 걸려있거나 결과물을 차례로 패싱하는 방식으로 구현해야한다면 메세지 큐같은 방식으로 비동기식 처리를 하는 방식을 적용해야할 때도 있음
Q. 암묵적인 표준을 존중해야하는가?
예시) 아키텍처적으로 깔끔한 코드가 기존의 암묵적인 표준(SpringBoot에서 최상위 도메인에 @Entity를 사용하는 등)을 위배하는 경우
A.
- 일관성이 가장 중요
- 암묵적인 표준이 이미 자리잡은 상황이라면 이를 존중해야함
- 하지만 문제점에 대해 알고 있어야 함
- 레거시 코드에 대해 무조건 새롭게 만들거나 처음 설계부터 다시 하거나 모든것을 다 고치겠다라는 식으로 접근하면 실패할 가능성이 매우 높음
- 레거시 코드에 대해서는 보수적으로 접근하는게 좋음
Q. 좋은 코드를 위한 원칙
A.
- 저자의 개인적인 생각으로는 DRY(Don’t Repeat Yourself)와 SRP(Single Responsibility Principle)이 중요하다고 생각
- DRY가 문제가 생기면 코드의 중복이 많다는 것이고 코드의 중복이 많으면 코드 하나 바꾸려면 모든 코드를 찾아보아야 하고 어떤것이 정답인지 알기 어려워지는 문제가 있음 (코드의 일관성 문제) -> 리팩토링 해야하는 주요한 지점이 됨
- SRP는 클래스와 모듈의 설계에 있어서 기준으로 잡고 가는것이 좋음
- 이 두가지는 레버리지를 하는데 좋음
레버리지란 지금 내가 투입할 시간과 노력 대신 다른 무언가를 이용하여, 더 적은 노력으로 성과를 창출하는 것
Q. 시간 vs 코드품질
A.
- 기술 부채는 불가피하므로 완전히 피할 수 없음
- 초반에는 일단 동작 중심으로 구현하도록 한다.
- 리팩터링은 일회성 이벤트가 아님을 생각할 것
- 지속적인 개선만이 유일한 해법 -> 눈사람 굴리기가 가능
Q. 성능 vs 가독성
A.
- 요즘 언어들, 컴파일러는 함수호출이 많아도 최적화를 공격적으로 함 + 컴퓨터 성능도 좋아졌음
- 콜 오버헤드와 같은 부분을 걱정하기보다는 가독성을 먼저, 기능을 먼저 염두해 두는 것이 좋음
- 기능을 구현했는데 문제가 있을 경우 프로파일러 등을 이용하여 병목지점을 찾고 해소하는 방식으로 가는 것이 좋음
Q. 리팩토링의 타이밍
A.
- 리팩토링의 시점은 개인이 판단하는 것
- 가장 손쉬운 방법
- DRY 위반 (코드 중복)이 3회가 되는 순간
- 중복 줄이기, 표현력 높이기, 초반부터 간단한 추상화 고려하기 by 론 제프리
- DRY 위반 (코드 중복)이 3회가 되는 순간
Q. 가독성의 기준은?
A.
- 깨꿋한 코드는 잘 쓴문장처럼 읽힌다. by 그레디 부치
- 깨끗한 코드의 특징은 많지만 그 중에서도 모두를 아우르는 특징이 하나 있다. 깨끗한 코드는 언제나 누군가 주의 깊게 짰다는 느낌을 준다. 고치려고 살펴봐도 딱히 손 댈 곳 없다. 작성자가 이미 모든사항을 고려했으므로 고칠 궁리를 하다보면 언제나 제자리로 돌아온다. 그리고는 누군가 남겨준 코드, 누군가 주의 깊게 짜놓은 작품에 감사를 느낀다. by 마이클 페더즈
- 보고 이해하기 쉬운 코드가 핵심
Q. 절차형 vs 객체지향
A.
객체지향과 함수형 프로그래밍 패러다임은 양립이 가능
- 절차적인 코드는 새로운 자료 구조를 추가하기 어려움 -> 모든 함수를 고쳐야함
객체지향 코드는 새로운 함수를 추가하기 어려움 -> 모든 클래스를 고쳐야함
- 어떤 시스템을 구현할 때, 새로운 자료 타입을 추가하는 유연성이 필요하면 객체가 더 적합
- 다른 경우로 새로운 동작을 추가하는 유연성이 필요하면 자료 구조와 절차적인 코드가 더 적합
Q. 기술부채 해결하기
A.
- 기술 부채는 개발에 있어 어쩔 수 없이 짊어져야 할 운명이라고 생각
- 장기적으로는 생산성을 떨어뜨리는 요인이므로 상환계획을 잘 잡아야함
켄트 벡이 제시한 세 가지 활동
- 먼저 동작하게 만들어라 -> 사업의 필수 요건
- 그리고 올바르게 만들어라 -> 리팩터링과 기능 개선
- 그리고 빠르게 만들어라 -> 리팩터링과 성능 개선
+) 코드를 만든 직후 테스트 케이스를 바로 만들어 두는 것이 좋음 -> 나중에 테스트 케이스를 만드는 것은 테스트 방안을 찾기 어렵기 때문에 -> 레거시 코드의 경우 영향을 최소화할 수 있는 테스트코드를 넣기 좋은 지점을 찾아 넣는 것이 중요
- 구현하면서 테스트까지 고려하는 것이 Best -> 코드 구현 후 테스트 코드 구현하는 것이 Good -> 한참 후에 여러 테스트 코드를 구현하는 것은 두통 그자체
Q. 주석을 꼭 없애야 할까?
A.
- 주석이 아닌 코드로 표현할 수 있으면 가장 좋음
- 반드시 필요한 경우에는 넣어야함
- 주석을 없애는 것이 클린코드의 목표가 아님
Q. 레거시 코드 리팩토링
A.
- 클린코드에 위배되는 레거시 코드는 있겠지만 코드 자체의 퀄리티가 좋은 경우
- 일관성이 매우 좋은 경우
- 이해가 어느정도 가능한 경우
- -> 굳이 바꾸지 않아도 된다.
Q. 지저분한 코드 해결 방법
A.
- 언제나 점진적인 개선
- 프로페셔널한 정신
- 덜 부끄러운 코드를 만드려는 노력
- 이러한 생각들을 가지고 코드를 작성하다보면 방법론 등은 상관없이 충분히 훌륭한 결과물을 창출 할 수 있을 것이라고 생각함