Clean Code - 2장 - 의미 있는 이름

Whale·2023년 2월 19일
0

CleanCode

목록 보기
2/6

의도를 분명히 밝혀라

좋은 이름을 지으려면 시간이 걸리지만, 좋은 이름으로 절약하는 시간은 훨씬 더 많다.
변수(혹은 함수나 클래스)의 존재 이유는? 수행기능은? 사용방법은? 따로 주석이 필요하다면 의도를 분명히 드러내지 못했기 때문이다.

ex>

public List<int [l> getThem() {
	List<int []> list1 = new ArrayList<int []>();
	for (int[] x : theList) 
    	if(x[0]= 4)
			list1.add(x);
	return listl; 
}

코드는 단순하지만, 어떤 의미가 있는지 알기 어렵다. 문제는 코드의 단순성이 아니라 함축성. 위 코드는 암암리에 독자가 다음과 같은 정보를 안다고 가정한다.
1. theList 에 무엇이 들어있는가?
2. theList 에서 0번째 값이 어째서 중요한가?
3. 값 4는 무슨 의미인가?
4. 함수가 반환하는 리스츠 list1 은 어떻게 사용하는가?

이를 아래와 같이 바꿀 수 있다.

public List<int []> getFlaggedCells() {
	List<int []> flaggedCells = new ArrayList<int []>(); 
    for (int [] cell : gameBoard)
	    if (cell[STATUS_VALUE] = FLAGGED) 
    		flaggedCells.add(cell);
	return flaggedCells;
}

theList 는 gameBoard 로. 0번째 값은 칸의 상태로. 4는 깃발이 꽂힌 상태를 지정한다. 각 개념에 이름만 붙여도 코드는 상당히 나아진다.

여기서 한번 더 수정을 가하면...

public <ListCell> getFlaggedCells () {
	List<Cell> flaggedCells = new ArrayList<Cell>(); 
    for (Cell cell : gameBoard)
    	if (cell.isFlagged())
	        flaggedCells.add(cell); 
	return flaggedCells;
}

int 배열 대신 Cell 이라는 클래스를 사용하고, isFlagged 라는 함수를 만들어서 좀 더 읽기 쉽게 만들 수 있다.

그릇된 정보를 피해라

코드에 잘못된 단서를 남겨서는 안된다. 나름대로 널리 쓰이는 의미가 있는 단어라도 다른의미로 해석될 여지가 있다.

잘못된 예
1. hp(hypotenuse, 빗변)

  • 잘못된 약어의 사용. hp 만 보고 빗변을 유추할 수 없다.
  • ...게임 HP...?
  1. accountList(하지만 실제 List 객체가 아님)
  • 실제로 List 객체를 쓰지 않지만, 의미로서 List 를 쓰게되면 프로그래머의 뇌에 과부화!
  • 이럴땐 List 라는 단어를 피해서, accountGroup 와 같이 명명을 바꿔야한다.

또다른 기가막힌 이야기. 소문자 l 이나 대문자 O 를 사용하는경우. 이 무슨 혼종...

int a = l;
if ( O == l )
	a = Ol; 
else
	l = Ol:

의미 있게 구분하라

컴파일러를 통과할지라도 연속된 숫자를 덧붙이거나 불용어를 추가하는 방식은 적절하지 못하다.
연속적인 숫자를 덧붙인 이름(a1, a2, ... aN) 은 의도적인 이름과 정 반대이다. 이런 이름은 그릇된 정보를 제공하는 이름도 아니며, 아무런 정보를 제공하지 못한다.

불용어를 추가한 이름 역시 아무런 정보도 제공하지 못한다. Product 를 예로들면, ProductInfo 와 ProductData 는 개념으로 구분되지 못하고 이름만 달리한다.

불용어
분석시 의미가 없는 단어. 인터넷 검색 시 검색 용어로 사용하지 않는 단어
관사, 전치사, 조사, 접속사 등 검색 색인 단어로 의미가 없는 단어
자주 등장하지만 문장을 분석하는 데 있어서는 큰 도움이 되지 않는 단어
예: and, in, to

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

발음하기 어려운 이름은 토론하기 어렵다. 혼자 개발하는것도 아니고... 다른 개발자와 논의하기 위해서는 발음하기 쉬운 이름을 사용하는것도 중요하다.
ex>

class DtaRcrd102 {
	private Date genymdhms:
	private Date modymdhms;
	private final String pszqint = "102";
	/* ... */
};
class Customer {
	private Date generationTimestamp;
	private Date modificationTimestamp;
	private final String recordId = "102"; /* ... */
};

다른사람과 이야기할떄 무엇이 더 좋은 방법인지는 명확하다.

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

남의 코드에서 특정한 키워드로 추적해야 할 상황을 가정하면, 한글자의 텍스트나 숫자등은 검색으로 찾기가 매우 힘들다. 무언가를 명명할때 찾아보기 쉽도록 명명하는 습관을 들여야 한다.

인코딩을 피해라

갑자기 네이밍 이야기에서 인코딩이 나와서 당황했는데. 여기서 말하는 인코딩은 옛날 IDE나 변수의 이름으로 타입을 추론했던 옛 유물에 관한 이야기.
요즘의 언어들은 컴파일러가 타입을 강제하고, 변수이름에 타입을 인코딩할 필요가 없다. 맴버의 접두사 등에도 불필요한 접두사가 붙을일이 없으니(private String mdsc 의 m 는 이제 왜 붙었는지도 모르는 유물.) 전부 필요없다.

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

인터페이스와 구현 클래스가 있을때에는 인코딩이 필요한 경우도 있다. 이는 결국 같이 개발하는 사람들끼리 맞춰야하는 규칙. 인터페이스를 다른 구현클래스들과 다르게 명명하고 싶다면 규칙을 만들어 붙이면 그만. 권장하진 않는다.

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

코드를 읽으면서 변수 이름을 자신이 아는 이름으로 변환해야 한다면 그 변수 이름은 바람직하지 못하다. 항상 명료함이 최고 라는 사실을 기억할것.

클래스 이름

클래스 이름과 객체 이름은 명사나 명사구가 적합하다. Customer, WikiPage, Account, AddressParser등이 좋은예다.
Manager, Procesor, Data,Info등과 같은 단어는 피하고, 동사는 사용하지 않는다.

메서드 이름

메서드 이름은 동사나 동사구가 적합하다. postPayment, deletePage, save등이 좋은예다.
접근자, 변경자, 조건자에 따라 값 앞에 get, set, is 를 붙인다.

기발한 이름은 피하라

코드에 개그 섞겠다고 장난치면 나중에 피본다... 재미난 이름보다는 명료한 이름을 선택하라.
특정 문화에서만 사용하는 농담은 피하고, 의도를 분명하고 솔직하게 표현하라.

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

추상적인 개념 하나에 단어 하나를 선택해 이를 고수한다. 예를들어, 똑같은 메서드를 클래스마다 fetch, retrieve, get 등으로 제각각 부르면 혼란이 온다. 일관성 있는 어휘를 지켜야한다.

말장난을 하지마라

너무 일관성을 고집하느라 미묘하게 다른 기능에 같은 일관성을 사용하면 곤란하다.
add 라는 메서드가 기존값 두개를 더하여 하나의 새로운 값을 만든다고 가정할때
새로 작성하는 메서드는 집합에 값을 추가한다고 생각해보자.
이때는 add로 일관성을 맞출게 아니라, insert 나 append 와 같은 이름이 되어야한다.

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

(...? 이게 무슨말이여...)
코드를 읽는 사람도 개발자이니, 알고리즘 이름, 패턴이름, 수학용어등을 사용하는건 ok.
모든 명명에 의미를 부여하는건 생각해봐야 할 문제...?

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

(...? 바로 위에서 쓰지 말라며...?)
적절한 프로그래머 용어가 없다면, 문제영역에서 이름을 가져온다...?

(아무래도 여기서 말하는 문제영역이란, 데이터가 가지는 의미로 보여진다. Customer, Shape 와 같은...?)

의미 있는 맥락을 추가하라

예를들어, firstName, lastName, street, houseNumber, city, state, zipcode 와 같은 변수들은 한번에 보게되면 주소에 대한 내용이라는 것을 알아챌 수 있지만 어떤 특정 구간에서는 state 만 사용한다고 가정해보자.
이를 주소의 state 라고 바로 말아채기는 힘들다. 이럴땐 마지막 방법으로 addr 이라는 접두어를 추가하는 방식을 생각해 볼 수 있다.
addrFirstName, addrLastName, addrstate 와 같이 쓰면 좀 더 맥락이 분명해진다.

(물론 가장 좋은건 Address 라는 클래스로 묶어두는것.)

불필요한 맥락을 없애라

일반적으로는 짧은 이름이 긴 이름보다 좋다. 단, 의미가 분명한 경우에 한해서. 이름에 불필요한 맥락을 추가하지 않도록 주의한다.

마치면서.

누군가 유료로 개발자 변수이름 제안 플러그인을 기똥차게 개발해낸다면 유료라도 쓰고싶다... 뭐 이리 신경쓸게 많담. ChatGPT 가 이름도 잘 제안해주는지 알아보러 가야겠다.

profile
그저 오래된 iOS 개발자.

0개의 댓글