일기/독서노트

『읽기 좋은 코드가 좋은 코드다』 정리①

망고고래 2024. 4. 7. 19:56

코드는 이해하기 쉬워야 한다

->코드는 다른 사람이 그것을 이해하는 데 들이는 시간을 최소화하는 방식으로 작성되어야 한다.

실제로는 혼자만 사용하는 코드라도 시간이 지난 뒤에 다시 코드를 보면 낯설게 보일 수 있다.

 

Ⅰ표면적 수준에서의 개선

1. 이름에 정보 담기

1)특정한 단어 고르기

아주 구체적인 단어를 선택해서 무의미한 단어를 피해야 한다.

ex)getPage()

로컬 캐시, 데이터베이스, 인터넷 중 어디에서 페이지를 가져오는 것인지 명확하지 않다. 인터넷에서 가져오는 경우라면 FetchPage() 또는 DownloadPage()가 더 의미있는 이름이다.

 

ex)int Size();

class BinaryTree{
    int Size();
    ...
}

여기서 size란 트리의 높이, 노드의 개수, 트리의 메모리 사용량 등 다양한 값으로 해석될 수 있다. 때문에 Height(), NumNodes(), MemoryBytes() 등이 더 의미 있는 이름이다.

 

ex)void Stop();

class Thread{
    void Stop();
    ...
}

다시는 되돌릴 수 없는 최종 동작을 수행하는 경우: Kill()

Resume()을 호출해서 다시 돌이킬 수 있는 동작인 경우: Pause()

 

단어 예시

send: deliver, dispatch, announce, distribute, route

find: search, extract, locate, recover

start: launch, create, begin, open

make: create, set up, vuild, generate, compose, add, new

 

2)보편적인 이름 피하기(tmp, retval)

변수의 이름은 변수의 목적이나 담고 있는 값을 설명해야 한다.

(1)retval

반환할 값으로 'retval'을 많이 쓰지만, 변수의 목적이나 담고 있는 값을 설명하는 이름을 가지면 반복문의 내용이 잘못 작성되었을 때 오류를 쉽게 알아차릴 수 있다.(예시: 제곱값의 누적합을 반환하는 경우: sum_squares)

(2)tmp

tmp라는 이름은 대상이 임시적으로만 존재하고, 임시저장소라는 역할이 주요한 용도일 때만 사용한다.

변수를 서로 교환하는 알고리즘의 경우

if(right < left){
    tmp = right;
    right = left;
    left = tmp;
}

tmp가 정말로 임시저장소외에 다른 용도가 없기 때문에 적당한 이름인 경우이다. 하지만 임시저장소 외의 기능이 있다면 그 기능에 맞춰서 이름을 지어야 한다. 또는 tmp라도 대상에 따라 이름을 다르게 해줄 수 있다.(tmp_file 등)

(3)루프반복자: i, j, iter, it

흔히 사용되며 반복자라는 의미를 충분히 전달함. 하지만 여기에 정보를 더해줄 수 있음(club_i, members_i, users_i 혹은 ci, mi, ui 등) -> 반복문이 여러 개 중첩되어있는 경우 명확하게 구별하기 쉬워짐

if(clubs[ci].members[ui] == users[mi])

위의 경우 ui와 mi가 바뀌었다는 것을 빠르게 알 수 있음