코드 정리법
보호 구문
함수를 읽을 때 다음과 같은 방식을 종종 볼 수 있습니다.
이런 코드는 다음과 같이 정리할 수 있습니다.
이런 식으로 코드를 정리하면 코드의 세부 사항을 알기 전 몇 가지 전제 조건이 있다고 보는 것과 동일하게 보일 수 있습니다.
안 쓰는 코드
안 쓰는 코드는 지워 버리세요. 그게 다입니다. 추후에 '어떡하지'라는 고민이 있을 수도 있지만, 형상 관리 도구가 해결해 줍니다.
대칭으로 맞추기
코드는 마치 유기체와 같이 성장합니다. 필요한 모든 코드를 한꺼번에 작성할 수는 없으니까요.
위 코드는 함수가 다른 방식으로 작성되어 있어 일관성이 없습니다. 하나는 if-else를 사용하고, 다른 하나는 switch-case를 사용하고 있죠. 이렇게 비대칭적으로 코드를 작성하면 유지보수가 어려울 수 있습니다.
코드를 읽을 때 기존과 다르면 '다른 동작의 코드겠지'라고 판단하게 됩니다. 같은 일임에도 다른 일인 것처럼 뜻이 흐려집니다. 때문에 한 가지 방식을 선택해서 일관되게 사용하는 것이 좋습니다.
새로운 인터페이스로 기존 루틴 부르기
루틴을 호출해야 하는데 기존 인터페이스 때문에 어렵거나 복잡하거나 지루해질 때가 있습니다. 이 모든 경우에 인터페이스를 새롭게 구현해서 호출하세요.
새롭게 구현한 인터페이스는 소프트웨어 설계에서 작은 단위로 중추적 역할을 합니다. 어떤 동작을 변경해야 할 경우, 변경하기가 한층 더 수월해집니다.
다음의 경우에도 비슷한 느낌을 받을 수 있습니다.
거꾸로 코딩하기: 루틴의 마지막부터 시작합니다. 마지막 줄에 이르기까지 필요한 결과는 모두 확보한 것처럼 코딩합니다.
테스트 주도 개발: 테스트부터 작성하여 통과 요건을 정합니다.
도우미 설계: 특정 업무를 수행하는 루틴, 객체, 서비스가 있다면 나머지 작업은 더 쉬워집니다.
읽는 순서
코드를 읽다가 전체를 이해하는 데 중요한 세부 사항을 마지막에야 만난다고 가정해봅시다. 이는 피로감을 유발하고, 읽는 사람을 지치게 만듭니다.
읽기 쉬운 순서대로 코드를 정렬하면 그 순서대로 코드를 파악할 수 있습니다.
코드를 읽을 때는 독자의 입장이 되어 보세요.
다른 코드 정리 작업을 함께하고 싶은 유혹이 있을지라도 뿌리치세요. 나중에 이들을 정리할 때가 있을 것입니다. 지금은 발견한 세부 사항을 정리하고, 읽는 순서에 맞추는 일을 다음 정리에서 처리하세요. 섞으면 안 됩니다.
언어에 따라 선언하는 순서에 민감할 때도 있습니다. 이러한 언어에서는 주의해야 합니다. 되도록 전체 파일의 순서를 바꾸는 대신, 읽는 순서가 중요한 것들부터 바꾸세요.
응집도를 높이는 배치
코드를 읽다가 변경해야 할 동작을 찾았는데 코드들이 흩어져 있으면 불편함을 느끼게 됩니다. 이럴 경우 변경할 요소들을 가까이 배치하면 됩니다.
선언과 초기화를 함께 옮기기
변수 선언과 초기화 위치가 서로 떨어져 있을 때가 있습니다. 변수 이름에서 힌트를 얻어 프로그램에서의 역할을 파악할 수 있지만, 변수 초기화는 이름이 주는 의미를 더 강화하기도 합니다. 때문에 변수를 선언하고 초기화하는 위치를 함께 옮기는 것이 코드를 이해하는 데 도움이 됩니다.
설명하는 변수
코드의 일부 표현식들은 시간이 지나면서 점점 커질 수 있습니다. 그 결과 나중에는 이해하기 어려울 정도로 복잡해지기도 합니다. 이런 경우 복잡한 표현식을 이해한 후, 표현식의 의도를 드러내는 변수 이름을 만들어 할당해 보세요.
위 코드를 다음과 같이 변경합니다.
설명하는 상수
코드를 읽다가 모르는 숫자를 볼 때가 있습니다. 해당 숫자를 파악하기 위해 코드를 분석해야 할 때가 많습니다. 이럴 때는 상징적인 숫자를 사용하여 의미를 명확히 하세요.
예를 들어, 에러 처리 로직에서 숫자 코드만으로는 의미를 알기 어렵다면, 상수를 만들어 사용하세요. 이는 다른 개발자가 코드를 이해하는 데 도움을 줄 것입니다.
해당 코드는 작성하지 않은 사람이 본다면 무슨 코드인지 알지 못합니다. 때문에 421가 나타내는 바를 알기 위해서는 서버측 담당자에게 연락을 하던지 코드를 살펴봐야 합니다.
명시적인 매개변수
매개변수를 객체로 전달하는 경우가 흔합니다. 하지만 이렇게 할 경우 어떤 데이터가 필요한지 파악하기 어려울 수 있습니다. 때문에 매개변수를 나눠서 받으면 코드를 읽고 테스트하기가 더 쉬워집니다.
비슷한 코드끼리 묶기
가장 간단한 코드 정리 방법 중 하나입니다. 긴 코드 덩어리를 읽다가 부분적으로 분리가 가능하다면 빈 줄을 넣어 분리하세요. 이렇게 관련된 코드들을 묶어두면 가독성이 향상됩니다.
도우미 추출
코드를 읽다가 목적이 명확하고 상호작용이 적은 코드 블록을 만날 때가 있습니다. 이러한 코드는 하나의 블록으로 추려내고 도우미 함수로 추출한 후, 이름을 붙이는 것이 좋습니다. 함수 이름은 작동 방식이 아닌 목적을 반영하도록 짓는 것이 중요합니다.
다음과 같이 변경합니다.
이렇게 변경하는 이유는 메인 로직의 줄 수를 줄일 수 있을 뿐 아니라, 도우미 함수에 의미 있는 이름을 붙여 코드를 읽는 데 도움을 주기 때문입니다.
하나의 더미
코드를 만드는 데 가장 큰 비용은 작성하는 것이 아니라 읽고 이해하는 데 드는 비용입니다. 코드 정리를 통해 더 작은 단위로 결합을 제거하고 응집도를 높일 수 있습니다.
다음과 같은 증상들을 찾아보세요.
길고 반복되는 인자 목록
반복되는 코드, 그중에서도 반복되는 조건문
도우미에 부적절한 이름
공유되어 변경에 노출된 데이터 구조
설명하는 주석
코드를 읽다가 '아, 이건 이렇게 동작하는구나!'라고 생각하는 순간이 있을 것입니다. 바로 그 순간을 기록하세요.
나와 성향이 다른 사람이라도, 그 누군가를 떠올리며 주석을 작성해보세요. 파일 앞에 주석이 없다면 설명을 추가하여 파일을 읽는 사람에게 유용한 정보를 제공할 수 있습니다. 또한 코드의 결함을 발견했다면 그 즉시 해당 위치에 주석을 다는 것이 좋습니다.
불필요한 주석 지우기
코드만으로 내용을 모두 이해할 수 있다면 주석을 지우세요. 가끔 모든 루틴에 주석을 달아야 한다는 규칙을 고집하는 사람도 있지만, 이러한 주석은 혜택 없이 비용만 발생시킵니다. 불필요한 중복이라면 삭제하세요.