본문 바로가기
Architecture

[Clean Code 정리] 의미있는 이름

by 테리는당근을좋아해 2022. 5. 28.

Clean Code - 의미있는 이름

 

1. 의도를 분명히 밝혀라

- 좋은 이름을 짓는 것은 시간이 걸리지만 좋은 이름으로 절약하는 시간이 더 많다.

 

# 안 좋은 예
# 코드의 함축성 문제 : 코드 맥락이 코드 자체에 명시적으로 드러나지 않는다.
def getThem(theList):
    return [x for x in theList if int(x[0]) == 1]

    
# 좋은 예
def getFlaggedValue(gameBoard):
    return [cell for cell in gameBoard if int(cell[0]) == 1]

 

 

 

2. 그릇된 정보를 피하라

- 그릇된 단서는 코드의 의미를 흐린다.

 

(1) 잘못 사용된 약어

- ex : hp. aix, sco

 

(2) 다른 의미를 갖는 네이밍

- 널리 쓰이는 의미가 있는 단어를 다른 의미로 사용해서는 안된다.

- 예를 들어, 여러 계정 그룹이 있을 때 리스트에 담기지 않는다면 accountList가 아닌 accoutGroup 등과 같은 표기를 사용한다. (List는 자료 형을 의미하기 때문)

 

(3) 흡사한 네이밍

- XYZControllerForEfficientHandlingOfStrings

- XYZControllerForEfficientStorageOfStrings

 

(4) 유사한 개념은 유사한 표기법을 사용

 

(5) 소문자 L과 대문자 O 변수의 사용

 

 

 

3. 의미있게 구분하라

- 단순히 컴파일러나 인터프리터를 통과하려는 코드를 구현하지 않는다.

 

(1) 의미가 불분명한 불용어

- 예 : ProductInfo와 ProductData

- 'Info'와 'Data'는 의미가 불분명한 불용어로써 다른 프로그래머가 두 변수를 구분하기 어렵게 만든다.

 

(2) 연속적인 숫자

- 예 : List1, List2, ...., ListN

 

# 안 좋은 예
def function1(list1, c):
    return [x for x in list1 if x == c]

# 좋은 예
def filter_by_condition(origin, condition)
    return [value for value in origin if value == condition]

 

(3) 안 좋은 변수명 예

- variable, nameString, name

- customer, customerObject

- moneyAmount, money

- accountDate, count, customerInfo, customer, theMessage, message

 

 

 

4. 발음하기 쉬운 이름을 사용하라

# 안 좋은 예
class DtaRcrd02():
    gnymdhms = None
    modymdhms = None
    pszqint = "102"
    
# 좋은 예
class Customer():
    generationTimestamp = None
    modificationTimestamp = None
    recordId = "102"

 

 

 

5. 검색하기 쉬운 이름을 사용하라

- 문자 하나를 사용하는 변수명이나 상수는 의도를 나타내지 못한다.

 

# 안 좋은 예
t = 0

for _ in range(0, 34):
    t += 4


# 좋은 예
from typing import Final

TOTAL_DAY: Final = 34
TASK_PER_DAY: Final = 4
total_task = 0

for _ in range(TOTAL_DAY):
    total_task += TASK_PER_DAY

 

 

 

6. 인코딩을 피하라

- 문제 해결에 집중하는 개발자에게 인코딩은 불필요한 부담이다.

- 인코딩한 이름은 발음하기 어렵고 오타가 발생하기 쉽다.

 

(1) 멤버 변수의 접두어

- 멤버 변수에 'm_'과 같은 접두어를 사용할 필요가 없다.

 

 

(2) 인터페이스와 구현 클래스의 네이밍

- 인터페이시 네이밍의 적절한 예 : IShapeFactory 또는 ShapeFactory

- 구현 클래스 네이밍의 적절한 예 : ShapeFactoryImpl, CShapeFacotryfh

 

 

 

7. 자신의 기억력을 자랑하지 마라

- 코드를 읽으면서 변수 이름을 개발자 본인만이 아는 이름은 적절하지 못하다.

- 남들이 읽었을 때, 이해하는 코드를 작성하라(루프문의 i, j, k는 허용가능하다.)

 

 

 

 

8. 클래스 이름

- 클래스 이름과 객체 이름은 명사나 명사구가 적합하다.

 

 

 

 

9. 메서드 이름

- 메서드 이름은 동사나 동사구가 적합하다.

- 접근자 : getXXX()

- 변경자 : setXXX()

- 조건자 : isXXX()

 

 

 

 

10. 기발한 이름은 피하라

- "재미난 이름", "특정 문화에만 사용되는 이름"은 피하고 통상적이면서 명료하고 의도를 분명하게 드러내는 표현을 사용하라

 

 

 

 

11. 한 개념에 한 단어를 사용하라

- 추상적인 개념 하나에 단어 하나를 선택해 이를 고수한다.

- 일관성 있는 어휘는 코드를 사용할 프로그래머가 반갑게 여길 선물이다.

 

 

 

 

12. 말장난을 하지마라

- 한 단어를 두 가지 목적으로 사용하지 마라

- 프로그래머는 코드를 최대한 이해하기 쉽게 짜야 한다.

- 대충 흝어봐도 이해할 코드 작성이 목표이다.

 

 

 

 

13. 해법 영역에서 가져온 이름을 사용하라

(1) 코드를 읽을 사람 또한 프로그래머다.

- 전산, 알고리즘, 패턴, 수학 용어와 같은 해법 영역에서 가져온 이름이 최선, 도메인이 차선

 

(2) 기술 개념에는 기술 이름이 가장 적합한 선택이다.

 

 

 

14. 문제 영역(domain)에서 가져온 이름을 사용하라

- 적절한 프로그래밍 용어가 없다면, 도메인에서 이름을 가져온다.

- 문제 영역과 관련이깊은 코드라면 도메인에서 이름을 가져와야 한다.

 

 

 

 

15. 의미있는 맥락을 추가하라

# 안 좋은 예
class LotOverHeadAnalysis():
    ...
    def calculate_lot_overhead(self, lot):
        if lot.type == 'None'
            return False
        if lot.id == 'None'
            return False
        
        prev_lot_id = lot.id - 1
        prev_lot = None
        while (prev_lot_id >= 0 and prev_lot_id < len(self.lots)):
            prev_lot = self.lots[prev_lot_id]
            if prev_lot.type == 'None':
                prev_lot_id -= 1
                continue
            if prev_lot.id == 'None':
                prev_lot_id -= 1
                continue
            break
        lot.lot_over_head = lot.start_time - prev_lot.end_time
        return True


# 좋은 예
class LotOverHeadAnalysis():
    ...
    def calculate_lot_overhead(self, lot):
        if self.__is_invalid_lot(lot):
            return False
        
        prev_lot = self.__get_prev_lot(lot)
        lot.lot_over_head = lot.start_time - prev_lot.end_time
        return True

    def __is_invalid_lot(self, lot):
        if lot.type == 'None'
            return False
        if lot.id == 'None'
            return False
        return True

    def __get_prev_lot(self, lot):
        prev_lot_id = lot.id - 1
        prev_lot = None
        while (prev_lot_id >= 0 and prev_lot_id < len(self.lots)):
            prev_lot = self.lots[prev_lot_id]
            if self.__is_invalid_lot(prev_lot):
                prev_lot_id -= 1
                continue
            return self.lots[prev_lot_id]
        return None

 

 

 

16. 불필요한 맥락을 없애라.

- 일반적으로 짧은 이름보다 긴 이름이 좋지만, 의미가 불분명할 경우에 해당한다.

- 이름에 불필요한 맥락을 추가하지 않도록 주의한다.

'Architecture' 카테고리의 다른 글

[Clean Code 정리] 객체와 자료구조  (0) 2022.05.29
[Clean Code 정리] 형식 맞추기  (0) 2022.05.29
[Clean Code 정리] 주석  (0) 2022.05.28
[Clean Code 정리] 함수  (0) 2022.05.28
[Clean Code 정리] 깨끗한 코드  (0) 2022.05.26

댓글