'나쁜 코드에 주석을 달지 마라. 새로 짜라'
- 브라이언 W. 커니핸,P.J. 플라우거
[개선 전]
// 직원에게 복지 혜택을 받을 자격이 있는지 검사한다
if (employee.flags & HOURLY_FLAG) && (employee.age > 65)
[개선된 코드]
if employee.isEligibleForFullBenefits()
많은 경우 주석으로 달려는 설명을 함수로 만들어 표현해도 충분하다.
// kk:mm:ss EEE, MMM dd, yyyy 형식이다.
let timeMatcher = Pattern.compile("\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d*")
// 여기서 trim 은 정말 중요하다. trim 함수는 문자열에서 앞, 뒤 공백을 제거한다.
// 문자열 앞, 뒤에 공백이 있으면 다른 문자열로 인식되기 때문이다.
let listItemContent = match.group(3).trimmingCharacters(in: [" "])
대다수 주석이 이 범주에 속한다.
// 월 중 일자
private let dayOfMonth: Int
// 전역 목록 <smodule>에 속하는 모듈이 우리가 속한 하위 시스템에 의존하는가?
if module.getDependSubsystems().contains(subSysMod.getSubSystem())
이 코드에서 주석을 없애고 다시 표현하면 다음과 같다.
let moduleDependencies = smodule.getDependSubSystems()
let ourSubSystem = subSysMod.getSubSystem()
if moduleDependencies.contains(ourSubSystem)
// Actions /////////////////////////////////////////////
닫는 괄호에 다는 주석: 중첩이 심하고 장황한 함수라면 의미가 있을지도 모르지만, 우리가 선호하는 작고 캡슐화된 함수에는 잡음일 뿐임.
따라서 만약 닫는 괄호에 주석을 달 생각이 든다면 함수를 줄이려 시도
주석으로 처리한 코드: 무언가 이유가 있으니깐 주석 처리를 한게 아닐까 싶어 다른 사람들이 지우기를 주저하게 만든다.
self.bytePos = writeBytes(pngIdBytes, 0)
//hdrPos = bytePos
writeHeader()
writeResolution()
//dataPos = bytePos
...
너무 많은 정보
주석에다 흥미로운 역사, 관련 없는 정보를 장황하게 늘어놓지 마라
ex) RFC 2045 의 역사
모호한 관계
: 코드에 대한 설명이 부족한 주석
/*
모든 픽셀을 담을 만큼 충분한 배열로 시작한다(여기에 필터 바이트를 더한다).
그리고 헤더 정보를 위해 200바이트를 더한다.
*/
self.pngBytes = new byte[(self.width + 1) * self.height * 3) + 200]
여기에서 필터 바이트란 무엇일까? 1이랑 관련이 있는건지? 아니면 *3이랑 관련이 있는건지?
그렇다면 200을 추가하는 이유는 ?
-> 주석을 다는 목적은 코드만으로 설명이 부족해서인데, 이 코드는 주석 자체가 다시 설명을 요구한다.
결국 맨 앞 장에서 나오는 문장 하나로 모든 내용의 정리가 가능하다고 생각한다.
'나쁜 코드에 주석을 달지 마라. 새로 짜라'
- 브라이언 W. 커니핸,P.J. 플라우거
과연 이 코드가 이해가 될 것인가? 고민해보고
그렇지 않다면 코드로 최대한 의도를 표현하고자 노력한 후
마지막 수단으로 주석을 사용해야 하지 않을까 생각한다.