[클린코드] 2장 의미 있는 이름

wlsh44·2022년 9월 27일
0

클린코드

목록 보기
2/8

의도를 분명히 밝혀라

의미 있는 이름은 개발을 할 때 가장 기본적이면서도 너무 중요하다.

디렉토리, 파일, 변수 등 개발을 하는 모든 곳에서 이름이 필요하고 이를 제대로 짓지 않으면 분명 언젠가 문제가 생긴다.

//좋지 않은 예
int a;
List<String> list;
if (num > 1) return;

무슨 의도로 작성한 코드인지 전혀 알 수 없으므로 언제나 사용 목적에 맞는 이름을 부여해야 한다.

if문에 있는 1 같은 매직넘버도 상수(static final)로 매핑을 해줘야 한다.

그릇된 정보를 피하라

코드가 사용되는 목적, 정보 를 정확하게 알려줄 수 있는 이름을 붙여야 한다.

특히 범용적으로 사용되는 축약어가 아닌 경우, 또는 단순 배열, 그룹과 같은 집합에 List와 같이 프로그래머에게 특별한 의미로 사용되는 이름을 사용하는 것은 피해야 한다.

IDE에서 유의미한 이름을 잘 제공하기 때문에 이를 활용하라는 말도 있었다.

의미있게 구분하라

예전에 xxxHandler xxxUtil 이런 식으로 클래스 명을 작성했다가 둘이 어떤 차이가 있는지 잘 모르겠다는 피드백을 받았다.
이와 같은 맥락인 것 같다.
어쩌면 Handler 라는 네이밍이 어떤 클래스를 다루기는 하지만 뭘 다루는지에 대해 알 수 없기 때문에 의도를 분명히 하지 않은 이름이기 때문에 발생한 문제일 수도 있다.

책에서는 문자열 복사 메서드에 들어가는 인자의 이름으로 예를 들고 있다.

public void copyChars(char a1[], char a2) {
	for (int i = 0; i < a1.length; i++) {
    	a2[i] = a1[i];
    }
}

a1과 a2를 보고 곧바로 어떤 변수가 source이고 destination인지 알 수 있다고 생각하지는 않는다.

이름을 보고 어떠한 역할을 하는지, 어떤 책임을 가지고 있는지 명확하게 알 수 있어야 한다.

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

의미를 담고 있지만 단순 숫자로 코딩되는 매직 넘버를 피해야 한다.

언제나 느끼는 거지만 개발할 당시에는 잘 알고있던 것들이 나중에 다시 보면 전혀 모르겠는 부분이 많다.

만약 로직이라면 천천히 코드를 살피며 따라갈 수 있지만 그냥 숫자로 적혀있는 매직 넘버는 끝내 이해하지 못하는 경우가 있다.

하지만 책에서 이름 길이는 범위 크기에 비례해야 한다 라는 문장을 강조하여 적어놓았는데 개인적으로는 와닿지 않는 부분이다.

예를 들어 메서드 내에서 단 한번만 쓰이는 변수라도 중요할 경우 상수 처리를 하는 것이 맞다고 생각하고 for문에서 단순 인덱스 i가 아닌 의미 있는 이름이 필요할 경우도 있다고 생각한다.

cv_accuracy = []
n_iter = 0

for train_index, test_index in kfold.split(features):
    #학습, 검증용 데이터 추출
    X_train, X_test = features[train_index], features[test_index]
    y_train, y_test = label[train_index], label[test_index]
    
    #학습
    dt_clf.fit(X_train, y_train)
    pred = dt_clf.predict(X_test)
    n_iter += 1

    #정확도 측정
    accuracy = np.round(accuracy_score(y_test, pred), 4)
    train_size = X_train.shape[0]
    test_size = X_test.shape[0]
    print('\n#{0} 교차 검증 정확도 :{1}, 학습 데이터 크기: {2}, 검증 데이터 크기: {3}'.format(n_iter, accuracy, train_size, test_size))
    print('#{0} 검증 세트 인덱스: {1}'.format(n_iter, test_index))
    cv_accuracy.append(accuracy)

print('\n## 평균 검증 정확도:', np.mean(cv_accuracy))

위 코드는 머신러닝에서 간단한 교차 검증 코드이다.

여기서 train_index , test_index 는 맨 처음 데이터 랜덤 추출할 때만 사용되었다.

하지만 만약에 이 이름을 i , j 로 했다면 지금처럼 머신러닝 공부에 손을 땐 내가 이 코드를 봤을 때 왜 이렇게 작성되어 있을까 하며 한 번 더 생각했을 것 같다.

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

위에서 했던 이야기와 같은 맥락이라고 생각한다.

나는 생각보다 더 멍청하다 😭

클래스 이름, 메서드 이름

클래스 이름은 명사, 메서드 이름은 동사로 지어야 한다. 어떤 클래스의 역할과 책임, 그에 대한 행동을 생각한다면 왜 이렇게 해야 하는지 쉽게 알 수 있다.

사람 이름도 동사로 짓지 않는다.

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

‘의미있게 구분하라’와 비슷하다. HandlerManager 등의 역할이 같다면 이를 통일시켜야 한다.

비슷한 예로 findget, removedelete , add append 등을 섞어 사용하지 말고 하나의 이름으로 일관성 있게 지어야 한다.

최근에 별 생각없이 코딩을 하다가 removedelete 를 섞어 쓴 기억이 있어 좀 더 인상깊게 읽었다.

의미 있는 맥락을 추가하라

단순 이름으로만 이름을 나타낼 수도 있다. 하지만 이 이름들이 하나의 맥락을 갖고 있다면 래퍼 클래스 등을 이용해 좀 더 큰 구조로 만들어주는 방식도 좋다.

책에 나온 예시가 제일 많이 사용되는 것 같다.

String firstName;
String lastName;
String street;
String houseNumber;
String city;
String state;

이 변수들이 한 곳에 모여있는 경우 ‘주소' 를 표현하려는 것을 알 수 있다.

하지만 firstName 이나 lastName , state 처럼 따로 사용했을 때 이 변수가 주소에서 나온 변수임을 파악하기는 쉽지 않다.

그렇기 때문이 이 변수들이 갖고 있는 ‘주소'라는 맥락을 통해 Address 라는 래퍼 클래스를 사용할 수 있다.
이 부분에 대해서 스터디를 할 때 맥락을 파악하는 방식을 조금 더 구체적으로 배웠다.

바로 변수들의 라이프 사이클을 생각하는 것이다.
실제로 맥락이 비슷한 변수들은 비슷하거나 같은 라이프 사이클을 가지고 있다.

느낀 점

사실 책을 읽을 때는 대부분 '아 맞지' '당연하지' 해도 막상 다시 이름을 지어야 하는 상황이 오면 막히게 되는 것 같다.
영어가 부족해서일까..😂

그리고 여태까지 혼자 개발을 진행해서 그런지 변수 명을 바꾸는데 큰 거리낌이 없었는데 나중에 협업을 하게 되었을 때 과연 내가 쉽게 변수 명을 바꿀 수 있을까 하는 걱정이 들기도 한다.

또 다른 사람이 변수 명을 바꾸었을 때 내가 쉽게 받아들일 수 있는 사람인가 궁금하기도 하다.
그럼에도 책에서는 다음과 같이 말한다.

여느 코드 개선 노력과 마찬가지로 이름 역시 나름대로 바꿨다가는 누군가 질책할지도 모른다.
그렇다고 코드를 개선하려는 노력을 중단해서는 안 된다.

이 말을 잊지 말자.

profile
정리정리

0개의 댓글