클린코드 2장 의미있는 이름 요약
·6 mins
의도를 분명히 밝혀라 #
- 좋은 이름을 지으려면 시간이 걸리지만 좋은 이름으로 절약하는 시간이 훨씬 더 많다.
- 이름을 주의깊게 살펴 더 나은 이름으로 개선한다면 코드를 읽는 사람이 좀 더 행복해지리라.
- 변수, 함수, 클래스 이름은 다음과 같은 굵직한 질문에 모두 답해야 한다.
- 존재 이유는? 수행 기능은? 사용 방법은?
- 따로 주석이 필요하다면 의도를 분명히 드러내지 못했다는 말이다.
- 코드 맥락이 코드 자체에 명시적으로 드러나야 한다.
- 단순히 이름만 고쳐도 함수가 하는 일을 이해하기 쉬워진다.
그릇된 정보를 피하라 #
- 프로그래머는 코드에 그릇된 단서를 남겨서는 안 된다.
- 예를들어 직각삼각형의 빗변으로 표현할 때 ‘hp’는 훌륭한 약어로 보일지라도 독자에게 그릇된 정보를 제공한다. (유닉스 변종을 가리키는 이름이기 때문에 헷갈릴 수 있다.)
- 여러 계정을 그룹으로 묶을 때, 실제 List가 아니라면 accountList라 명명하지 마라.
- 프로그래머에게 List는 특수한 의미이다.
- 실제 List가 아니라면 프로그래머에게 그릇된 정보를 제공한 셈이다.
- accountGroup, bunchOfAccounts나 단순히 Accounts라 명명하는게 낫다.
- 서로 흡사한 이름을 사용하지 않도록 주의하라.
- 유사한 개념은 유사한 표기법을 사용해야 한다.
- 일관성이 떨어지는 표기법은 그릇된 정보다.
- IDE의 자동완성 기능은 주석까지 노출해주지 않는다.
의미 있게 구분하라 #
- 컴파일러나 인터프리터만 통과하려는 생각으로 코드를 구현하는 프로그래머는 스스로 문제를 일으킨다.
- 컴파일러를 통과할지라도 연속된 숫자를 덧붙이거나 불용어(noise word)를 추가하는 방식은 적절하지 못하다.
- 이름이 달라야 한다면 의미도 달라져야 한다.
- 연속적인 숫자를 덧붙인 이름(a1, a2, a3…)는 아무런 정보를 제공하지 못한다. 저자의 의도도 드러나지 않는다.
- Info나 Data와 같은 단어는 a, an, the와 마찬가지로 의미가 불분명한 불용어이다.
- ProductInfo, ProductData 이 두 이름은 개념을 구분하지 않은 채 이름만 달리한 경우다. 아무런 정보를 제공하지 못한다.
- 명확한 관례가 없다면 money와 moneyAmount는 구분이 안 된다. 읽는사람이 차이를 알도록 이름을 짓자.
발음하기 쉬운 이름을 사용하라 #
- 발음하기 어려운 이름은 토론하기 어렵다.
검색하기 쉬운 이름을 사용하라 #
- 문자 하나를 사용하는 이름과 상수는 텍스트 코드에서 쉽게 눈에 띄지 않는다는 문제점이 있다.
- ‘MAX_CLASSES_PER_STUDENT’는 검색으로 찾기 쉽지만, 숫자 7은 어렵다.
- e라는 문자도 변수 이름으로 적합하지 못하다. 대부분의 프로그램의 모든 문장에서 등장한다.
- 이런 관점에서 긴 이름이 짧은 이름보다 좋다.
- 검색하기 쉬운 이름이 상수보다 좋다.
인코딩을 피하라 #
- 굳이 부담을 더하지 않아도 이름에 인코딩할 정보는 아주 많다.
- 유형이나 범위 정보까지 인코딩에 넣으면 그만큼 이름을 해독하기 어려워진다.
- 요즘 나오는 프로그래밍 언어는 많은 타입을 지원하고, IDE에서는 코드를 컴파일 하지 않고도 타입오류를 감지할 정도로 발전했다.
- 이제는 헝가리식 표기법이나 기타 이름에 타입을 표기하는 방식은 오히려 방해가 될 뿐이다.
- 인터페이스 클래스와 구현 클래스
- 개인적으로 밥아저씨는 인터페이스 이름은 접두어를 붙이지 않는 편이 좋다고 생각한다.
- 다루고 있는 클래스가 인터페이스라는 사실을 남에게 알리고 싶지 않다.
- 클래스의 사용자는 그냥 ShapeFactory라고만 생각하면 좋겠다.
- 인터페이스 클래스 이름과 구현 클래스 이름 중 하나를 인코디해야 한다면 구현 클래스 이름을 택하겠다. (ShapeFactoryImp가 IShapeFactory 보다 낫다)
자신의 기억력을 자랑하지 마라 #
- 독자가 코드를 읽으면서 변수 이름을 자신이 아는 이름으로 변환해야 한다면, 그 변수 이름은 바람직하지 못하다.
- 일반적으로 문제 영역이나 해법 영역에서 사용하지 않는 이름을 선택했기 때문에 생기는 문제다.
- 전문가 프로그래머는 명료함이 최고라는 사실을 이해한다.
- 전문가 프로그래머는 자신의 능력을 좋은 방향으로 사용해 남들이 이해하는 코드를 내놓는다.
클래스 이름 #
- 클래스 이름과 객체 이름은 명사나 명사구가 적합하다.
- Customer, WikiPage, Account, AddressParser 등
- Manager, Processor, Data, Info 등과 같은 단어는 피하고, 동사는 사용하지 말자.
메서드 이름 #
- 메서드 이름은 동사나 동사구가 적합하다.
- postPayment, deletePage, save 등
- 접근자, 변경자, 조건자는 표준에 따라 값 앞에 get, set, is를 붙인다.
기발한 이름은 피하라 #
- 이름이 너무 기발하면 저자와 유머 감각이 비슷한 사람만, 그리고 농담을 기억하는 동안만 이름을 기억한다.
- 특정 문화에서만 사용하는 농담은 피하는 편이 좋다.
- 의도를 분명하고 솔직핟게 표현하라
한 개념에 한 단어를 사용하라 #
- 추상적인 개념 하나에 단어 하나를 선택해 이를 고수하자.
- 같은 메서드를 클래스마다 fetch, retrieve, get으로 제각각 부르면 혼란스럽다.
- 메서드 이름은 독자적이고 일관적이어야 주석을 뒤져보지 않고도 프로그래머가 올바른 메서드를 선택할 수 있다.
말장난을 하지마라 #
- 한 단어를 두 가지 목적으로 사용하지 마라.
- 때로는 프로그래머가 같은 맥락이 아닌데도 ‘일관성’을 고려해 한 단어로 두 가지 역할을 수행하도록 한다.
- 여러 클래스에서 add라는 메서드를 ‘숫자를 더함’의 의미로 사용하고 있는 상황에서 ‘집합에 값을 추가’하는 메서드를 만들 때는 ‘insert’, ‘append’와 같은 이름을 사용해야 한다.
- 일관성을 위해 다른 목적의 메서드를 같은 이름인 add로 부른다면 이는 말장난이다.
- 프로그래머는 코드를 최대한 이해하기 쉽게 짜야 한다.
- 집중적인 탐구가 필요한 코드가 아니라 대충 훑어봐도 이해할 코드 작성이 목표다.
- 의미를 해독할 책임이 독자에게 있는 논문 모델이 아니라 의도를 밝힐 책임이 저자에게 있는 잡지 모델이 바람직하다.
해법 영역 가져온 이름을 사용하라 #
- 코드를 읽을 사람도 프로그래머이므로 전산용어, 알고리즘 이름, 패턴 이름, 수학 용어 등을 사용해도 괜찮다.
- 모든 이름을 문제 영역(도메인)에서 가져오는 정책은 현명하지 못하다.
문제 영역에서 가져온 이름을 사용하라 #
- 적절한 프로그래머 용어가 없다면 문제 영역(도메인)에서 이름을 가져온다.
- 그러면 코드를 보수하는 프로그래머가 분야 전문가에게 의미를 물어 파악할 수 있다.
- 우수한 프로그래머와 설계자라면 해법 영역과 문제 영역을 구분할 줄 알아야 한다.
의미 있는 맥락을 추가하라 #
-
스스로 의미가 분명한 이름이면 좋지만, 대다수 이름은 그렇지 못하다.
-
그래서 클래스, 함수, 이름 공간에 넣어 맥락을 부여한다.
- state라는 이름만 보고 주소라고 유추하기 어렵다.
- addr 접두어를 추가해서 addrState라 쓰면 맥락이 좀 더 분명해진다.
-
함수 예시
function printGuessStatistics(candidate: string, count: number) { let number: string, verb: string, pluralModifier: string; if (count === 0) { number = "no"; verb = "are"; pluralModifier = "s"; } else if (count === 1) { number = "1"; verb = "is"; pluralModifier = ""; } else { number = count.toString(); verb = "are"; pluralModifier = "s"; } console.log(`There ${verb} ${number} ${candidate}${pluralModifier}`); }
이 함수의 이름은 맥락의 일부만 제공하며, 알고리즘이 나머지 맥락을 제공한다. 함수를 끝까지 읽어보고 나서야 number, verb, pluralModifier라는 변수 세 개가 ‘통계 추측’ 메시지에 사용된다는 사실이 드러난다. 맥락을 유추하는건 독자의 몫이 된다. 그냥 메서드만 훑어서는 세 변수의 의미가 불분명하다.
class GuessStatisticsMessage { number: string; verb: string; pluralModifier: string; make(candidate: string, count: number) { this.createPluralDependentMessageParts(count); console.log(`There ${this.verb} ${this.number} ${candidate}${this.pluralModifier}`); } createPluralDependentMessageParts(count: number) { if (count === 0) { this.thereAreNoLetters(); } else if (count === 1) { this.thereIsOneLetter(); } else { this.thereAreManyLetters(count); } } thereAreNoLetters() { this.number = "no"; this.verb = "are"; this.pluralModifier = "s"; } thereIsOneLetter() { this.number = "1"; this.verb = "is"; this.pluralModifier = ""; } thereAreManyLetters(count: number) { this.number = count.toString(); this.verb = "are"; this.pluralModifier = "s"; } }
위와 같이 GuessStatisticsMesssage라는 클래스를 만든 후 세 변수를 클래스에 넣으니 변수의 맥락이 분명해졌다. 이렇게 맥락을 개선하면 함수를 쪼개기 쉬워지고 알고리즘도 더 명확해진다.
불필요한 맥락을 없애라 #
- ‘고급 휘발유 충전소(Gas Station Deluxe)’라는 애플리케이션을 짤 때 모든 클래스의 이름을 GSD로 시작하겠다는 생각은 바람직 하지 못하다.
- 일반적으로 짧은 이름이 긴 이름보다 좋다. 단, 의미가 분명한 경우에 한해서만.
- 그러므로 이름에 불필요한 맥락을 추가하지말자.
- accountAddress, customerAddress는 Address 클래스 인스턴스로는 좋은 이름이나 클래스 이름으로는 적합하지 못하다.
마치면서 #
- 좋은 이름을 선택하려면 설명 능력이 뛰어나야 하고 문화적인 배경이 같아야 한다.
- 좋은 이름을 선택하는 능력은 기술, 비즈니스, 관리 문제가 아니라 교육 문제다. 우리 분야 사람들이 이름 짓는 방법을 제대로 익히지 못하는 이유는 이 때문이다.
- 사람들이 이름을 바꾸지 않으려는 이유 하나는 다른 개발자가 반대할까 두려워서다.
- 우리들 대다수는 자신이 짠 클래스 이름과 메서드 이름을 모두 암기하지 못한다.
- 암기는 요즘 나오는 도구에게 맡기고, 우리는 문장이나 문단처럼 읽히는 코드 아니면 적어도 표나 자료 구조처럼 읽히는 코드를 짜는데만 집중해야 마땅하다.
- 여느 코드 개선 노력과 마찬가지로, 이름 역시 나름대로 바꿨다가 누군가의 질책을 받을 지 모르지만 그렇다고 코드를 개선하려는 노력을 중단해서는 안된다.