본문 바로가기
스터디/Clean Code

Ch2. 의미 있는 이름

by 헤콩 2023. 2. 24.
반응형
1장은 클린코드가 왜 필요한지, 대부분의 코드가 왜 복잡해지고 더러워지는지, 클린코드란 무엇인지를 다뤘다.

2장부터는 코드를 클린하게 만들 수 있도록 본격적으로 시작하는 장이며, 이 챕터에서는 주로 이름(변수명, 함수명 등)을 잘 짓는 법에 대해 다룬다.

왜 이름을 잘 지어야 할까? 코드는 나 혼자만의 것이 아니다. 여러 사람들과 일을 할 때, 누군가 내 코드를 보았을 때, 한 눈에 이해할 수 있도록 코드를 깨끗하게 잘 다듬어야 한다.
그 중에 첫 단계가 바로 이름을 잘 짓는 것이다.

 

목차

더보기

목차

1. 의도를 분명히 밝혀라

2. 그릇된 정보를 피하라

3. 의미 있게 구분하라

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

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

6. 인코딩을 피하라

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

8. 클래스 이름

9. 메서드 이름

10. 기발한 이름은 피하라

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

12. 말장난을 하지 마라

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

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

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

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


1. 의도를 분명히 밝혀라

이름만으로도 이 변수나 함수가 어떤 일을 하는지, 어떤 의도를 가지고 사용되는 변수/함수인지를 알 수 있도록 해야합니다.

 

아래 예시를 살펴 봅시다.

getThem( ) getFlaggedCells( )

지뢰찾기 게임을 만든다고 가정해봅시다.

이때 getThem()의 경우,

        ❌무엇을 얻어오려고 하는지,

        ❌왜 x[0]이 4일 때 list1에 넣어주는지,

        ❌4는 무슨 의미인지,

        ❌반환되는 list1은 뭘 담은 것인지

알 수 없습니다.

 

그러나 getFlaggedCells()의 경우,

        함수명에서 깃발이 꽂힌 칸을 얻어올 것이라는 의도를 알아챌 수 있습니다.

        flaggedCells가 깃발이 꽂힌 칸이 담긴 리스트일 것임을 알 수 있습니다.

        gameBoard는 지뢰찾기의 게임보드 칸임을 알 수 있습니다.

        isFlagged()를 통해 cell에 깃발이 꽂혀있으면 flaggedCells 리스트에 담는다는 것을 알 수 있습니다.

 

단순히 이름만 고쳤는데도 함수가 하는 일을 이해하기 쉬워졌고,

바로 이것이 좋은 이름이 주는 위력입니다.

 

 

2. 그릇된 정보를 피하라

# 나름대로 널리 쓰이는 의미를 가진 단어를 다른 의미로 사용하면 안됩니다.

예를 들어, hp, aix, sco는 유닉스 플랫폼이나 유닉스 변종을 가리키는 단어이므로 변수 이름으로 적합하지 않습니다.

 

# 서로 흡사한 이름을 사용하지 않도록 주의해야 합니다.

==> 유사한 개념은 유사한 표기법을 사용합니다.

==> 이것도 정보이기 때문에 일관성이 떨어지는 표기법은 그릇된 정보입니다.

 

또한, 그릇된 정보가 담긴 변수 이름의 예로 L이나 O를 들 수 있습니다.

L이나 O를 변수 이름으로 쓸 경우, 아래의 예시처럼 1과 0으로 혼동할 위험이 있습니다.

int a = l;

if (O == l) a = O1;
else l = 01;

 

 

3. 의미 있게 구분하라

변수 이름을 보고 변수들의 의도나 목적을 구분 할 수 있어야 합니다.

변수 이름에 연속된 숫자나 불용어(noise word)를 추가하는 방식은 적절하지 못합니다.

이름이 달라야한다면 의미도 달라야 합니다.

        ❌ a1, a2, a3...

        ❌ Name과 NameString은 의미상 차이가 없으므로 중복되는 변수입니다.

        ❌ ProductInfo와 ProductData는 변수 이름만 보고는 무슨 차이가 있는지 알 수 없습니다.

        ❌ 마찬가지로 Customer와 CustomerObject 또한 차이를 알 수 없습니다.

 

즉, 읽는 사람이 차이를 알도록 이름을 지어야 합니다.

 

 

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

프로그래밍은 하나의 사회활동이라고 할 수 있기 때문에, 발음하기 쉬운 이름을 사용해야 합니다.

발음하기 어렵다면 협력할 때 서로 커뮤니케이션 하기 어렵고, 어려운 만큼 의미를 담기도 힘들기 때문에 변수에 대해서 설명이 필요해지기 때문입니다.

발음하기 어려운 이름 발음하기 쉬운 이름

 

 

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

문자 하나를 사용하는 이름과 상수는 검색해도 쉽게 눈에 띄지 않습니다.

예를 들어 변수에 7이라는 상수가 있어 7을 검색했을 때, 7이 들어가는 파일 이름이나 수식이 모두 검색되기 때문입니다. 마찬가지로 e라는 문자도 변수 이름으로 적합하지 않습니다.

이런 관점에서 긴 이름이 짧은 이름보다 좋습니다.

=> 검색하기 쉬운 이름이 상수보다 좋습니다.

 

이름을 의미있게 지으면 길이가 길어지지만, 길이가 긴 이름은 검색이 쉬워집니다.

 

 

6. 인코딩을 피하라

* 인코딩 : 사용자가 입력한 문자나 기호들을 컴퓨터가 이용할 수 있는 신호로 만드는 것

유형이나 범위 정보까지 인코딩에 넣으면 그만큼 이름을 해독하기 어려워집니다.

인코딩한 이름은 거의 발음하기 어려우며 오타가 생기기 쉽습니다.

 

- 헝가리식 표기법

* 헝가리식 표기법 : 컴퓨터 프로그래밍에서 변수나 함수의 이름에 그 종류, 곧 흔히 데이터 타입 따위를 명시하는 표기법

java처럼 강한 타입(strongly-typed) 언어라면, 타입을 컴파일러에서 체크하므로 자료형을 변수명 넣을 필요가 없습니다. 객체는 강한 타입이며, IDE는 코드를 컴파일하지 않고도 타입 오류를 감지할 정도로 발전했기 때문입니다.

 

- 멤버 변수 접두어

클래스와 멤버 변수를 구분하는 접두어를 이름에 붙일 필요가 없습니다. 클래스와 멤버 변수를 색으로 구분해주는 IDE를 사용하거나 그만큼 적게 사용하는 것이 맞기 때문입니다.

 

- 인터페이스 클래스와 구현 클래스

예를 들어 추상 팩토리 패턴을 사용한다고 하면, 인터페이스 클래스와 구현 클래스의 이름을 지어야합니다.

그래서 굳이 둘 중 하나에 인코딩을 해야 할 상황이 생긴다면, 인터페이스 보다는 구현 클래스 이름에 인코딩하는 게 좋습니다.

인터페이스 이름에 인코딩을 하게 되면, 과도한 정보전달이 이루어지거나 주의가 흐트러진다고 말합니다.

 

그리고 개인적인 의견을 추가하자면, 더 많이 보게 되는 클래스는 인터페이스보다 구현 클래스 이기 때문에, 더 많이 사용을 하게 되는 구현 클래스 이름을 구체적으로 작성하는게 좋다고 생각합니다.

 

 

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

코드는 자기 자신만 보는 게 아니기 때문에,

변수 이름을 자신만 아는 단어나 한 자리 수 글자로 설정하는 것은 다른 사람이 자신이 이해한 개념의 이름으로 바꿔야 하는 불상사가 일어나게 만듭니다.

보통 한 자리 수 글자는 루프에서 반복 횟수를 세는 i, j, k같이 루프 범위에서 사용됩니다.

 

우리는 변수 이름에 상관 없이 모두 어떤 용도의 변수였는지 기억하는 똑똑한 프로그래머가 되는 것보다,

명료함이 최고임을 아는 전문가 프로그래머가 되어야 합니다.

* 명료함 : 뚜렷하고 분명함

 

 

8. 클래스 이름

클래스 이름과 객체 이름은 동사나 특별한 개념이 없는 Info, Data 등을 제외한 명사명사구가 적당합니다.

 

 

9. 메서드 이름

메서드 이름은 동사동사구가 적당합니다.

 

아래와 같은 예시를 보면 좀 더 이해하기 쉽습니다.

날씨라는 데이터를 얻어오는 접근자(Accessor) 메서드는 getWeather()

날씨라는 데이터를 다시 세팅해주는 변경자(Mutator) 메서드는 setWeather()

어떠한 배열이 비어있는지 확인해주는 조건자(Predicate) 메서드는 isEmpty()

 

생성자(Constructor)를 오버로딩 하는 경우, [1]번 코드가 [2]번코드보다 좋다

[1] Complex fulCrumPoint = Complex.FromRealNumber(23.0);

[2] Complex fulCrumPoint = new Complex(23.0);

 

 

10. 기발한 이름은 피하라

재미난 이름보다 명료한 이름을 선택해야 합니다.

특정 문화에서만 사용하는 농담을 이름으로 짓는 것을 피하고, 의도를 분명하고 솔직하게 표현해야 합니다.

 

 

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

추상적인 개념 하나에 단어 하나를 선택하여 고수해야합니다.

여러 클래스에서 같은 메소드를 제각각 다른 이름으로 부른다면 어떤 클래스에서 어떤 이름으로 부르는지 기억하기 어렵기 때문입니다.

따라서 메서드 이름은 독자적이고 일관적이어야 합니다.

그래야 주석을 뒤져보지 않고도 올바른 메서드를 선택할 수 있습니다.

 

 

12. 말장난을 하지 마라

한 단어를 두 가지 목적으로 사용하면 안됩니다.

예를 들어, 여러 클래스에 add라는 메서드가 있을 때, 각 클래스의 add라는 메소드의 매개변수나 반환값이 의미적으로 같다면 문제가 없습니다.

 

하지만 지금까지 이 add라는 이름의 메서드가 어떠한 두 매개변수를 더하는 의미를 가지고 있다고 했을 때,

어떠한 집합에 원소 하나를 더한다는 의미의 새로운 메서드에도 '일관성'을 고려하여 add라는 이름을 붙여도 될까요?

 

안됩니다. 의미상 목적이 다르기 때문에 add가 아닌 insert라는 이름을 붙이거나 하여 한 단어를 두 가지 목적으로 사용하지 않도록 해야합니다.

 

 

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

코드를 읽을 사람도 프로그래머이기 때문에 전산 용어, 알고리즘 이름, 패턴 이름, 수학 용어 등을 사용해도 괜찮습니다. 모든 이름을 의미상으로 짓는다면, 같은 개념을 다른 이름으로 부르던 서로 다른 프로그래머들은 혼동이 올 수 있기 때문입니다.

따라서 기술개념에는 기술이름이 가장 적합한 선택입니다.

 

 

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

적절한 기술이름(프로그래머 용어)이 없다면 문제 영역에서 이름을 가져옵니다.

우수한 프로그래머와 설계자라면 해법 영역과 문제 영역을 구분할 줄 알아야 한다. 문제 영역 개념과 관련이 깊은 코드라면 문제 영역에서 이름을 가져와야 한다.

(memo) 사실 무슨 말인지 잘 이해하지 못했다. 문제 영역이 무엇인지, 해법 영역이 무엇인지 이해가 필요하다.

 

 

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

예를 들면,

firstName, lastName, street, houseNumber, city, state라는 변수가 있을 때,

전반적으로 살펴보면 주소와 관련된 변수임을 알 수 있습니다.

하지만 어떤 메소드는 state만 사용한다고 가정하면 state 하나만 보았을 때 주소와 관련된 변수임을 알기 힘듭니다. 이럴 때 addr이라는 접두어를 추가하면 맥락을 분명하게 할 수 있습니다.

addrFirstName, addrLastName, addrStreet, ...

 

그래서 클래스, 함수, 이름 공간에 의미를 넣어 맥락을 부여합니다. 모든 방법이 실패하면 마지막 수단으로 접두어를 붙입니다.

 

 

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

예를 들어,

영화 리스트(Movie List) 애플리케이션을 개발한다고 가정할 때, 모든 클래스 이름을 ML로 시작하는 것은 바람직하지 않습니다.

일반적으로 의미가 분명한 경우에 한해서 짧은 이름이 긴 이름보다 좋습니다.

즉, 이름에 불필요한 맥락을 추가하지 않도록 해야합니다.

 

 

 

 

 

2장을 마치며..

변수나 클래스 이름에 의미와 개념, 맥락을 부여해서 내가 아닌 다른 사람이 코드를 볼 때 무슨 의도인지 한 눈에 들어올 수 있도록 노력해야한다. 하지만 불필요한 맥락은 제거하여 혼잡해지지 않도록 하자.

반응형

'스터디 > Clean Code' 카테고리의 다른 글

Ch4. 주석  (0) 2023.02.24
Ch3. 함수  (0) 2023.02.24

댓글