👮♀️ 이름을 잘 짓는 간단한 규칙 몇 가지 소개
1. 의도를 분명히 밝혀라
- 좋은 이름을 지으려면 분명 시간이 걸리지만, 좋은 이름으로 절약하는 시간이 훨씬 더 많다.
- '변수, 함수, 클래스'의 이름은 '존재 이유, 수행 기능, 사용 방법' 이라는 질문에 답할 수 있어야 한다.
주석이 필요한 순간 의도를 분명히 드러내지 못한 것.
(x)
var d = 5
(o)
var day = 5
2. 그릇된 정보를 피하라
- 프로그래머는 코드에 그릇된 단서를 남겨서는 안 된다.
- 실제 List 가 아니라면 List를 이름에 넣지 않는 편이 바람직하다.
- 실제 List 라고 하더라도 List 를 넣지 않는 편을 권장
ex) 계정을 그룹으로 묶는 경우, accountList 보다는 accounts 를 권장.
accounts 만으로도 배열이라는 것을 알릴 수 있음
- 서로 흡사한 이름을 사용하지 않도록 주의한다.
겁나게 비슷한 이름
ex) XYZControllerForEfficientHandlingOfStrings
ex) XYZControllerForEfficientStorageOfStrings
3. 의미 있게 구분하라
- a, a1
- 이미 product 라는 이름이 존재한다는 이유만으로 (다른 이름이 필요할 때) productInfo 라고 붙이면 안된다.
ex) customer / customerInfo, account/accountData, message/messageString
- 책에서는 -Info, -Data, -String 등의 단어를 덧붙이는 것을 지양함.
Customer, CustomerInfo, CustomerData 의 본질적인 차이가 무엇인지 구별하기가 힘듦
- (평소에도 Data, Info 를 많이 사용하여 반성하게 되는 부분)
스터디 중 나온 다양한 의견
- 대등한 관계라면 suffix 보다는 prefix 를 붙여서 구분 -> suffix 를 붙이면 구별하기가 힘듦
- 만약 포함 관계라면 이너 클래스를 사용
4. 발음하기 쉬운 이름을 사용하라
- genymdhms (generate date, year, month, day, hour, minute, second)
- 젠야무다함즈 ???
-> 장) 재미있음, 단) 변수의 의미를 설명해줘야 함
- generationTimestamp 로 바꾸면 재미는 없지만 설명할 필요가 없는 변수 이름을 사용할 수 있음
5. 검색하기 쉬운 이름을 사용하라
for i in 0..<34 {
s += (t[j] * 4) / 5
}
- 만약 여기서 5를 찾게 되면, 5를 포함한 모든 단어가 나타난다.
- 또한 코드 자체의 의미 파악도 쉽지 않다.
하지만 아래와 같이 각 상수, 변수에 대해 의미를 부여하게 되면,
let realDaysPerIdealDay = 4
let WORK_DAYS_PER_WEEK = 5
var sum = 0
for i in 0..<NUMBER_OF_TASKS) {
let realTaskDays = taskEstimate[i] * realDaysPeridealDay
let realTaskWeeks = realTaskDays / WORK_DAYS_PER_WEEK
sum += realTaskWeeks
}
- 함수가 길어진다.
- 하지만 그만큼 단어의 검색이 쉬워지고, (WORK_DAYS_PER_WEEK)
코드의 의미 파악 또한 쉬워진다. (주당 근무일수)
6. 인코딩을 피하라 (타입 명시X)
- 옛날에는 컴파일러가 타입을 점검하지 않았으므로 프로그래머에게 타입을 기억할 단서가 필요했다.
- 하지만 지금은 컴파일러가 타입을 점검해주므로 변수명에 타입을 적어줄 필요가 없다.
7. 클래스 이름
- 클래스 이름, 객체 이름은 명사나 명사구가 적합하다
- 좋은 예: Customer, WikiPage, Account, AddressParser
- 나쁜 예: -Manager, -Processor, -Data, -Info
이후 이어지는 메서드 이름은 생략한 이유
메서드 이름뿐만 아니라 클래스 이름까지,
언어마다 큰 차이가 있고 예외사항도 많기 때문에 클린 코드의 내용을 그대로 받아들이는 것 보다는,
각 언어에서 권장되는 네이밍 컨벤션을 찾아보고
iOS, 안드로이드 등 기존 프레임워크의 클래스, 메서드에서 어떠한 네이밍 패턴을 가지는지 참고하면 좋을 것 같음.
예를 들어 Java에서는 반환 값이 있는 메서드에 대해 get 을 권장하는 반면,
Swift 에서는 get 을 사용하지 않음.
또한 iOS 에서는 isHidden 을 사용하는 반면 안드로이드에서는 VISIBLE, INVISIBLE 등을 사용함.
이를 두고 아래 링크에서는 '(의미 & 문법이 적절한) 영어 + 컨벤션 = 잘 읽히는 코드' 라고 표현.
Swift 개발자처럼 변수 이름 짓기
8. 한 개념에 한 단어를 사용하라
- 어떤 값을 받는 똑같은 메서드를 객체마다 fetch, retrieve, get 으로 제각각 부르면 혼란스러울 수 있다. 일관성을 지켜야 한다.
- 하지만, 한 개념에 한 단어를 사용하라는 이유로 다른 맥락인데도 억지로 같은 이름의 메서드를 사용할 필요는 없다.
ex) append, insert 둘 다 기존 배열에 새 값을 추가하는 메서드이지만, 맥락이 다르다.
9. 의미 있는 맥락을 추가하라
- 어떤 메서드 안에 state 라는 변수만 하나 달랑 있으면 그 의미를 파악하기가 힘들다. (어떤 나라의 주? 상태?)
- 주소와 관련된 의미로 사용할 경우 addr 이라는 접두어를 추가해 addrState 로 쓰면 맥락이 좀 더 분명해진다.
- 혹은 상황에 따라 Address 라는 클래스를 만들고 멤버 변수로 state 를 사용할 수 있다.
10. 불필요한 맥락을 없애라
- 상황에 따라 맥락 없이도 의미를 충분히 파악할 수 있는 경우가 존재함.
- 의미를 충분히 파악할 수 있는 경우 이름에 불필요한 맥락을 넣지 않는다.
let address = Address()
address.state
address.addrState
그럼 상태에 대해 다룰 때는 state vs status ?
여러 자료를 찾아본 결과 대부분
여러 결과 상태 중 하나를 나타내는 것은 status
ex) success, fail
일련의 과정 중 특정 상태 하나를 명시할 때는 state
ex) 동기화 전 -> 동기화 중 -> 동기화 완료
출처: 링크
위와 같은 개념을 토대로 생각해보니 status code 가 왜 state code 가 아닌지 알 수 있을 것 같음.
결론
- 사람인 이상 모든 클래스, 메서드, 변수명을 외울 순 없다.
- 클래스, 메서드, 변수명을 외울 시간에 차라리 우리는 암기가 필요 없을 만큼 바로 읽힐 수 있는 네이밍을 통해 오로지 코드 짜는 데에만 집중해야 한다.
여러 자료를 함께 찾아보며 느낀 개인적인 결론
- 이 책에서 말하는 바를 공식처럼 대입하려기보다는 상황에 따라 유연하게 적용할 필요가 있다고 생각.
예를 들어 실제 Swift의 URL 이라는 클래스 안에는 절대 주소를 의미하는 프로퍼티 2개(absoluteURL, absoluteString)가 존재.
타입명을 프로퍼티에 명시하지 말라고 했다는 이유로 URL이나 String 을 제외한다면 구분이 되지 않을 것임.
이 경우엔 의미 있는 맥락을 추가한 것으로 이해해야 함.
- 즉, 포인트를 책에 있는 규칙 자체에만 집중하기 보다는 다른 사람이 이해할 수 있는가? 에 두고 이 규칙들을 적용해 나가면 좋을 것 같음.
그리고 실제로 책에서도 다른 사람이 읽을 수 있는지에 관점을 맞추며 이를 굉장히 강조하고 있음.