일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 프로그래머스
- Coursera
- Java
- AI Mathematics
- 데이터 사이언스
- 코세라
- string
- Boostcamp AI
- Data Science
- 클린코드 파이썬
- Python
- 코테
- 파이썬
- softeer
- IBM
- data science methodology
- 데이터사이언스
- 소프티어
- 데이터과학
- 알고리즘
- programmers
- 자바
- 티스토리챌린지
- 클린코드
- Clean Code
- 문자열
- 부스트캠프
- 깨끗한 코드
- 코딩테스트
- 오블완
- Today
- Total
떼닝로그
[2장] 의미 있는 이름 본문
의도를 분명히 밝혀라
- 좋은 이름을 지으려면 시간이 걸리지만, 좋은 이름으로 절약하는 시간이 훨씬 더 많다.
# 좋지 않은 예시
d = 0 # 경과 시간(단위: 날짜)
# 좋은 예시
elapsedTimeInDays = 0
daysSinceCreation = 0
daysSinceModification = 0
fileAgeInDays = 0
- 이름 d는 아무 의미도 드러나지 않는다. 측정하려는 값과 단위를 표현하는 이름이 필요하다.
- 의도가 드러나는 이름을 사용하면 코드 이해와 변경이 쉬워진다!
def getThem() -> List(int):
list1 = ArrayList()
for x in theList:
if x[0] == 4:
list1.append(x)
return list1
- 코드 맥락이 코드 자체에 명시적으로 드러나야 한다.
- 단순히 이름만 고쳤음에도 함수가 하는 일을 이해하기 쉬워질 수 있다. 이것이 좋은 이름이 주는 위력
그릇된 정보를 피하라
- 서로 흡사한 이름을 사용하지 않도록 주의해야 한다.
ex. XYZControllerForEfficientHandlingOfStrings와 XYZControllerForEfficientStorageOfStrings... 엄청 비슷하다
- 유사한 개념은 유사한 표기법을 사용한다. 이것도 정보!...
- 일관성이 떨어지는 표기법은 그릇된 정보
- 이름으로 그릇된 정보를 제공하는 진짜 끔찍한 예가 소문자 L이나 대문자 O 변수...
의미 있게 구분하라
- 이름이 달라야 한다면 의미도 달라져야 한다.
- 연속적인 숫자를 덧붙인 이름(a1, a2, ..., aN)은 의도적인 이름과 정반대. 아무런 정보를 제공하지 못하는 이름.
- 함수 인수 이름으로 source나 destination을 사용한다면 코드 읽기가 훨씬 더 쉬워진다
- 불용어를 추가한 이름 역시 아무런 정보도 제공하지 못한다.
Product, ProductInfo, ProductData라는 클래스가 있다면... 개념을 구분하지 않은 채 이름만 달리한 경우.
Info나 Data는 a, an, the와 마찬가지로 의미가 불분명한 불용어
- 불용어는 중복이다. 변수 이름에 variable, 표 이름에 table이라는 단어 들어가면... 안됨
getActiveAccount()
getActiveAccounts()
getActiveAccountInfo()
- 읽는 사람이 차이를 알도록 이름을 지어라!
발음하기 쉬운 이름을 사용하라
- 발음하기 쉬운 이름은 중요하다. 프로그래밍은 사회 활동.
# 1
class DtaRcrd102:
__genymdhms = 0
__modymdhms = 0
__pszqint = "102"
# 2
class Customer:
__generationTimestamp = 0
__modificationTimestamp = 0
__recordId = "102"
- genymdhms... 젠와이디에이취엠에스... 으악
- 두번째 코드를 사용하면 지적인 대화가 가능해진다.
검색하기 쉬운 이름을 사용하라
- 문자 하나를 사용하는 이름과 상수는 텍스트 코드에서 쉽게 눈에 띄지 않는다
- 간단한 메서드에서 로컬 변수만 한 문자를 사용한다. 이름 길이는 범위 크기에 비례해야 한다.
# 1
for j in range(0, 34):
s += (t[j]*4)/5
# 2
realDaysPerIdealDay = 4
WORK_DAYS_PER_WEEK = 5
sum = 0
for j in range(0, NUMBER_OF_TASKS):
realTaskDays = taskEstimate[j] * realDaysPerIdealDay
realTaskWeeks = (realTaskDays / WORK_DAYS_PER_WEEK)
sum += realTaskWeeks
- 이름을 의미 있게 지으면 함수가 길어지지만, 정말정말 찾기 쉬워진다.
인코딩을 피하라
- 문제 해결에 집중하는 개발자에게 인코딩은 불필요한 정신적 부담.
헝가리식 표기법
- 헝가리식 표기법은 기존 표기법을 완전히 새로운 단계로 끌어올렸다.
- 컴파일러가 타입을 기억하고 강제한다. 클래스와 함수는 점차 작아지고 있다... -> 변수를 선언한 위치와 사용하는 위치가 멀지 않다
멤버 변수 접두어
- 멤버 변수에 m_이라는 접두어를 붙일 필요도 없다.
- 클래스와 함수는 접두어가 필요 없을 정도로 작아야 마땅하다.
- 멤버 변수를 다른 색상으로 표시하거나 눈에 띄게 보여주는 IDE를 사용해야 마땅하다.
# 1
class Part:
__m_dsc = 0
def setName(name:String):
__m_dsc = name
# 2
class Part:
self.description = ""
def setDescription(self, description:String):
self.description = description
자신의 기억력을 자랑하지 마라
- 독자가 코드를 읽으면서 변수 이름을 자신이 아는 이름으로 변환해야 한다면 그 변수 이름은 바람직하지 못하다.
- 문제 영역이나 해법 영역에서 사용하지 않는 이름을 선택했기 때문에 생기는 문제
- 문자 하나만 사용하는 변수 이름은 문제가 있다... (루프에서 반복 횟수를 세는 변수 i, j, k는 괜찮다. l은 절대 안돼!)
- 전문가 프로그래머는 명료함이 최고 라는 사실을 이해하고, 자신의 능력을 좋은 방향으로 사용해 남들이 이해하는 코드를 내놓는다.
클래스 이름
- 클래스 이름과 객체 이름은 명사나 명사구가 적합하다.
ex. Customer, WikiPage, Account, AddressParser는 OK. Manager, Processor, Data, Info의 단어는 피하기
- 동사는 사용하지 않는다.
메서드 이름
- 메서드 이름은 동사나 동사구가 적합하다.
ex. postPayment, deletePage, save는 OK.
- 접근자(Accessor), 변경자(Mutator), 조건자(Predicate)는 javabean 표준에 따라 값 앞에 get, set, is를 붙인다.
name = employee.getName()
customer.setName("mike")
if paycheck.isPosted() ...
- 생성자를 중복정의(overload) 할 때는 정적 팩토리 메서드를 사용한다. 메서드는 인수를 설명하는 이름을 사용한다.
# 좋음
fulcrumPoint = Complex.FromRealNumber(23.0)
# 별로
fulcrumPoint = Complex(23.0)
- 생성자 사용을 제한하려면 해당 생성자를 private으로 선언한다.
기발한 이름은 피하라
- 재미난 이름보다 명료한 이름을 선택하라
- 특정 문화에서만 사용하는 농담은 피하는 편이 좋다.
- 의도를 분명하고 솔직하게 표현하라.
한 개념에 한 단어를 사용하라
- 추상한 개념 하나에 단어 하나를 선택해 이를 고수한다.
- 메서드 이름은 독자적이고 일관적이어야 한다. 그래야 주석을 뒤져보지 않고도 프로그래머가 올바른 메서드를 선택한다.
- 일관성 있는 어휘는 코드를 사용할 프로그래머가 반갑게 여길 선물이다.
말장난을 하지 마라
- 한 단어를 두 가지 목적으로 사용하지 마라. 다른 개념에 같은 단어를 사용한다면 그것은 말장난에 불과하다.
- 프로그래머는 코드를 최대한 이해하기 쉽게 짜야 한다.
- 집중적인 탐구가 필요한 코드가 아니라, 대충 훑어봐도 이해할 코드 작성이 목표다.
해법 영역에서 가져온 이름을 사용하라
- 코드를 읽을 사람도 프로그래머이기 때문에 전산 요엉, 알고리즘 이름, 패턴 이름, 수학 용어 등을 사용해도 괜찮다.
- 기술 개념에는 기술 이름이 가장 적합한 선택이다.
문제 영역에서 가져온 이름을 사용하라
- 적절한 프로그래머 용어가 없다면, 문제 영역 개념과 관련이 깊은 코드라면 문제 영역에서 이름을 가져와야 한다.
- 우수한 프로그래머와 설계자라면 해법 영역과 문제 영역을 구분할 줄 알아야 한다.
의미 있는 맥락을 추가하라
- 클래스, 함수, 이름 공간에 넣어 맥락을 부여한다. 모든 방법이 실패하면 마지막 수단으로 접두어를 붙인다.
- firstName, lastName, street, houseNumber, ... 변수를 훑어보면 주소라는 사실을 금방 알아차린다.
- addrFirstName, addrLastName, addrState라고 위의 변수들에 addr라는 접두어를 추가하면 맥락이 조금 더 분명해짐을 볼 수 있다.
- 함수 이름은 맥락 일부만 제공하며, 알고리즘이 나머지 맥락을 제공한다.
# 맥락이 불분명한 변수
def printGuessStatistics(candidate:char, count:int):
number = ""
verb = ""
pluralModifier = ""
if count == 0:
number = "no"
verb = "are"
pluralModifier = "s"
elif count == 1:
number = "1"
verb = "is"
pluralModifier = ""
else:
number = str(count)
verb = "are"
pluralModifier = "s"
guessMessage = print(f"There {verb}, {number}, {candidate}, {pluralModifier}")
print(guessMessage)
# 맥락이 분명한 변수
class GuessStatisticsMessage:
def __init__(self, None):
__number = ""
__verb = ""
__pluralModifier = ""
def make(self, candidate:str, count:int) -> str:
self.createPluralDependentMessageParts(count)
return f"There {verb}, {number}, {candidate}, {pluralModifier}"
def createPluralDependentMessageParts(self, count:int):
if count == 0:
self.thereAreNoLetters()
elif count == 1:
self.thereIsOneLetter()
else:
self.thereAreManyLetters(count)
def thereAreManyLetters(self, count:int):
self.number = str(count)
self.verb = "are"
self.pluralModifier = "s"
def thereIsOneLetter(self):
self.number = "1"
self.verb = "is"
self.pluralModifier = ""
def thereAreNoLetters():
self.number = "no"
self.verb = "are"
self.pluralModifier = "s"
불필요한 맥락을 없애라
- 일반적으로는 짧은 이름이 긴 이름보다 좋지만, 의미가 분명한 경우에 한해서다.
- 이름에 불필요한 맥락을 추가하지 않도록 주의한다.
'개발로그 > Clean Code' 카테고리의 다른 글
[6장] 객체와 자료 구조 (0) | 2022.12.09 |
---|---|
[5장] 형식 맞추기 (0) | 2022.12.02 |
[4장] 주석 (0) | 2022.11.16 |
[3장] 함수 (0) | 2022.11.02 |
[1장] 깨끗한 코드 (0) | 2022.10.31 |