읽기 좋은 코드가 좋은 코드다.

읽기쉬운 코드가 좋은 코드다.

Table of Contents

  1. Packing Information into Names
  2. Names That Can’t Be Misconstrued
  3. Summary

1. Packing Information into Names

변수명을 쉽게 짓는다는 의미보다 제 3자가 봤을때도 충분히 의도를 눈치 챌수 있는 변수명을 짓는 것을 목표

1-1. Choose Specific Words

// inappropriate
getPage(url)

// appropriate
fetchPage(url)
downloadPage(url)

get이 의미하는 바가 명확하지 않음. 데이터베이스에서 받는 것인지 아니면 인터넷에서 가져오는 것인지. 인터넷에서 가져온다고 한다면 fetchPage나 downloadPage가 적절함. 물론 전달해주는 param으로 유추할 수도 있음.

// inappropriate
class Thread {
    public void stop();
}

// appropriate
class Thread {
    public void kill();

    public void pause();
    public void resume();
}

stop이 적절할 수도 있지만. 안에 선언된 함수에 따라서

Finding More “Colorful” Words

유의어 색인집을 잘 활용하자

1-2. Avoid Generic Names tmp and retval

return value

var euclidean_norm = function (v) {
    var retval = 0.0;
    for (var i = 0; i < v.length; i += 1)
        retval += v[i] * v[i];
    return Math.sqrt(retval);
};
var euclidean_norm = function (v) {
    var sum_squares = 0.0;
    for (var i = 0; i < v.length; i += 1)
        sum_squares += v[i] * v[i];
    return Math.sqrt(sum_squares);
};
retval += v[i];
sum_squares += v[i]; // Where's the "square" that we're summing? Bug!

temp

temp 같은 변수명은 책임을 회피하는 것(물론 정말 임시저장은 ok)

if (right < left) {
    tmp = right;
    right = left;
    left = tmp;
}
String tmp = user.name();
tmp += " " + user.phone_number();
tmp += " " + user.email();
...
template.set("user_info", tmp);

Even though this variable has a short lifespan, being temporary storage isn’t the most important thing about this variable. Instead, a name like user_info would be more descriptive.

// inappropriate
saveData(temp, ...)

// appropriate
saveData(tempFile, ...)

Looking at just this one line of code, it isn’t clear if tmp is a file, a filename, or maybe even the data being written.

1-3. Prefer Concrete Names over Abstract Names

// inappropriate
serverCanStart()

// appropriate
canListenOnPort()

1-4. Attaching Extra Information to a Name

// inappropriate
id()

// appropriate
hexID()

Values with Units

var start = (new Date()).getTime(); // top of the page
...
var elapsed = (new Date()).getTime() - start; // bottom of the page
document.writeln("Load time was: " + elapsed + " seconds");
var start_ms = (new Date()).getTime(); // top of the page
...
var elapsed_ms = (new Date()).getTime() - start_ms; // bottom of the page
document.writeln("Load time was: " + elapsed_ms / 1000 + " seconds");

Encoding Other Important Attributes

1-5. How Long Should a Name Be?

보편적으로 짧은 변수명보다는 의미를 설명하는 긴 변수명이 더 유용하다고 알려져 있음.

newNavigationControllerWrappingViewControllerForDataSourceOfClass

The longer a name is, the harder it is to remember, and the more space it consumes on the screen, possibly causing extra lines to wrap.

Shorter Names Are Okay for Shorter Scope

small “scope” don’t need to carry as much information.

근거 : 앞 뒤 문맥을 보고 쉽게 파악이 가능하므로

if (debug) {
    map<string,int> m;
    LookUpNamesNumbers(&m);
    Print(m);
}

Even though m doesn’t pack any information, it’s not a problem, because the reader already has all the information she needs to understand this code.

// inappropriate at global 
LookUpNamesNumbers(&m);
Print(m);

큰 범위를 갖는다면 이름에 타입이나 목적을 명시

Typing Long Names—Not a Problem Anymore

변수명이 길어진다면 IDE에서 지원하는 자동완성으로 해결. 앞에 몇글자만 외우면 된다.

Acronyms and Abbreviations

보편적인 축약은 인정한다. 새 팀원이 왔을때도 쉽게 유추가 가능한가? 특정 프로젝트에만 국한되는 것 역시 허용이 되지 않는다. 다른사람이 프로젝트에 합류하면 속뜻을 알기 어렵다.

Throwing Out Unneeded Words

convertToString()
toString()
// inappropriate
doServeLoop()

// appropriate
serveLoop()

2. 오해할 수 없는 이름들

// inappropriate
clip(text, length)
// inappropriate
clip(text, maxLength)
// appropriate
truncates(text, maxLength)

2-1. Prefer min and max for Limits

// inappropriate
CART_TOO_BIG_LIMIT = 10
if shopping_cart.num_items() >= CART_TOO_BIG_LIMIT:
Error("Too many items in cart.")

you can fix

if shopping_cart.num_items() > CART_TOO_BIG_LIMIT:
if shopping_cart.num_items() > MAX_ITEMS_IN_CART:

2-2. Prefer first and last for Inclusive Ranges

Does this print [2,3] or [2,3,4] (or something else)?

// inappropriate
print integer_range(start=2, stop=4)

Although start is a reasonable parameter name, stop can be interpreted in multiple ways here.

// appropriate
print integer_range(min=2, max=4)

2-3. Prefer begin and end for Inclusive/Exclusive Ranges

// easy
PrintEventsInRange("OCT 16 12:00am", "OCT 17 12:00am")
// not easy
PrintEventsInRange("OCT 16 12:00am", "OCT 16 11:59:59.9999pm")

Unfortunately, English doesn’t have a succinct word for “just past the last value.”

2-4. Naming Booleans

// appropriate
isUserAuthenticated = true;
neePassword = true;

adding words like is, has, can, or should can make booleans more clear.

bool disable_ssl = false;
bool use_ssl = true;

2-5. Matching Expectations of Users

이미 저장된 값을 가져온다면 getMean이 맞겠지만, iterate해서 새로 계산한다면 computeMean()이 더 장확하다. 연산 시간의 차이도.

3. Summmary

The best names are ones that can’t be misconstrued—the person reading your code will understand it the way you meant it, and no other way. Unfortunately, a lot of English words are ambiguous when it comes to programming, such as filter, length, and limit. Before you decide on a name, play devil’s advocate and imagine how your name might be misunderstood. The best names are resistant to misinterpretation.

Extras