[읽기좋은 코드가 좋은 코드다] 클린코드 압축버전

Uno·2021년 8월 25일
0

Book

목록 보기
5/9

책을 읽으며 메모한 글입니다.
(간단한 메모이므로 반말에 대한 부분 양해 부탁드립니다~!)

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


- 가독성의 기본 정리

핵심아이디어

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

작가는 저에게 이렇게 말합니다.
“상상 속에 존재가 너의 코드를 본다고 생각해라!”
이렇게 생각하며 코드 하는 것은 메타인지에도 좋고 스스로에게도 큰 발전이 있는 습관이라고 생각해요!

Part One 표면적 수준에서의 개선

여기서 말하는 “표면적” 이라는 뜻은 좋은 이름 짓기, 좋은 설명 달기, 보기 좋게 정렬하기 와 같은 걸들입니다.

2. 이름에 정보 담기


핵심아이디어

이름에 정보를 담아라

안좋은 예시로 드는 것들은 다음과 같습니다. tmp, size, 와 get 입니다. 앞으로 이름에 정보를 담는 것에 대해 구체적으로 알려드리겠습니다.

  • 특정한 단어 고르기
    이름에 정보를 담는 방법 중 하나는 아주 ::구체적인 단어::를 선택하는 것입니다.

책에서는 더 ‘화려한’ 단어를 고르라고 했는데, 제 생각엔 화려안 단어라기보다는 좀 더 구체화된 단어가 맞을 것 같습니다. 꼭 머리속에서 상상할 수 있을 정도의 단어라고 보는게 맞을 것 같아요. 그래서 보통 사용되는 애매모호한 단어와 이를 대체할 수 있는 단어들을 설명해줍니다.

send -> deliver, dispatch, annuouce, distribute, route
find -> search, extract, locate, recover
start -> launch, create, begin, open
make -> create, set up, build, generate, compose, add, new

개인적으론 우측의 단어들이 무언가 상상이 된다고 할까요? 어떤 동작인지 머리속에서 그림이 그려집니다. 좌측 그림도 불가능한 것은 아니지만, 무언가 중의적으로 해석될 여지가 있죠.

핵심 아이디어

재치 있는 이름보다 명확하고 간결한 이름이 더 좋다.

  • tmp나 retval 같은 보편적인 이름 피하기
    예시가 자바스크립드로 되어 있어서 swift로 변경해보겠습니다.
var computeNorm: Int {
	var retval = 0
	for i in 0 ... arrayInt.count { // arrayInt는 입력된 값입니다.
		retval += i * i
	}
	return sqrt(retval)
}

(제가 자바스크립트를 잘 이해를 못해서 잘못 옮겼을 가능성 * Swift작성의 실수 가 있을 수 있으므로 감안해서 읽어주세요)

여기서 주목해야할 이름은 retval 입니다. 이 단어가 “반환값이구나” 라고 생각할 수는 있으나 너무 불분명하다고 합니다. 그래서 sum_squrares 와 같이 어떤 것인지 정확히 알 수 있는 단어로 변경하라고 추천합니다.

핵심 아이디어

retval이라는 이름은 정보를 제대로 담고 있지 않다. 대신 변수값을 설명하는 이름을 사용하라.

  • tmp
    내용을 요약하자면, 진짜 잠시 저장하는 용도가 아니면 tmp라는 단어 사용을 자제하라고 합니다
    조언

    tmp라는 이름은 대상이 짧게 임시적으로만 존재하교, 임시적 존재 자체가 변수의 가장 중요한 용도일 때에 한해서 사용해야 한다.

  • 루프반복자
    i, j, iter, it 과 같은 이름을 피하라고 권장합니다. 이 대신 다음과 같은 것들을 사용하라고 합니다.

members_i
users_i 
mi
ui
  • 보편적인 이름에 대한 판결문
    조언

    tmp, it, retval와 같은 이름들을 사용하게 될 때는 반드시 그런 이유가 있어야한다.

  • 추상적인 이름보다 구체적인 이름을 선호하라
    무언가 설명하기보다는 예시를 보여드리겠습니다.

안 좋은 예시)
ServerCanStart()

좋은 예시)
CanListenOnPort()

이 예시를 보면서 어떤 기준으로 원리로 좋은예시로 변경했을지 고민해봤습니다. 안 좋은 예시는 주어 + 동사 로 구성이 되어있더라구요. 좋은 예시는 동사 + 목적어 혹은 동사 + 보어 로 구성되었습니다.
(개인적인 생각입니다.)

또 다른 예시입니다.
안좋은 예시)
DISALLOW_EVIL_CONSTRUCTORS()

좋은 예시)
DISALLOW_COPY_AND_ASSIGN()

이 두 예시는 모두 동사 + 목적어 로 구성되어 있죠. 차이가 있다면 “EVIL” 이라는 주관적인 평가가 들어간 단어가 있는 점입니다. “CONSTRUCTORS” 또한 논란의 여지가 있죠. 즉, 금지하는 대상이 무엇인지 한 번더 고민하게 만듭니다. 그렇기에 좋은 예시처럼 좀더 구체적으로 작성할 필요가 있습니다.

다른 예시입니다.
안좋은 예시)
—run_locally

좋은 예시)
—extra_logging
—use_local_database

좋은 예시와 안좋은 예시의 기준은 다음과 같습니다.
- 팀에 새로 합류한 사람은 “—run locally”를 보고 목적어가 무엇인지 생각해야만 합니다. 그리고 run locally라는 예시는 여러가지 기능을 포괄할 수 있는 단어입니다. 하나의 단어에 하나의 기능이 아니라 여러가지를 추가되므로 모호합니다.

  • 추가적인 정보를 이름에 추가하기
    16진수 문자열을 담는 변수가 있다고 생각해봅시다.
var id: String // Example: "af84ef845cd8"

이럴 경우 id가 아니라 “hex_id” 가 낫다고 조언합니다. 예시를 보지 않더라도 바로 알 수 있으니까요.

  • 단위를 포함하는 값들
    예시입니다.
var start = newData().getTime()
...
var elapsed = (newData().getTime) - start
document.writeIn("Load time was: " + elpased + " seconds")

이 코드는 웹페이지를 로딩하는 시간을 측정하는 코드입니다.

getTime이라는 것을 받아서 변수에 할당할 때, 단위가 있음에도 이를 명시하지 않았습니다. 한 번더 생각하게 만드는 코드이므로 다음과 같이 구체화하여 단위를 명시해주는 것이 좋다고합니다.

var start_ms = newData().getTime()
...
var elapsed_ms = (newData().getTime()) - start_ms
document.writeIn("Load time was: " + elapsed_ms / 1000 + " seconds")

개선방안에 대한 예시입니다.

start(delay: Int) 				// start(delay_secs: Int)
createCache(size: Int)	 		// createCache(size_mb: Int)
throttleDownload(limit: Float) // throttleDownload(max_kpbs: Float)
rotate(angle: Float)			   //  rotate(degrees_cw: angle) 
  • 다른 중요한 속성 포함하기
    단위에만 추가적인 정보를 붙이는 것이 아니라 보안에 관련된 요소에도 적용할 수 있습니다.

상황1)
패스워드가 ‘plaintext’에 담겨 있고, 추가적인 처리를 하기 전에 반드시 암호화 되어야한다.
기존의 변수명)
password
개선된 변수명)
plaintext_password (swift로 바꾸자면 plaintextPassword 정도?)

상황2)
사용자에게 보여지는 설명문이 화면에 나타나기 전에 이스케이프 처리가 되어야한다.
기존의 변수명)
comment
개선된 변수명)
unescaped_comment (swift로 바꾸자면 unescapedComment)

상황3)
html의 바이트가 UTF-8으로 변환되었다.
기존의 변수명)
html
개선된 변수명)
html_utf8

상황4)
입력데이터가 “url encoded” 되었다.
기존의 변수명)
html
개선된 변수명)
data_URLenc

책에서는 그렇다고 모든 변수에 추가적인 정보를 담을 필요는 없다고 말합니다. 추가적인 정보를 다는 기준은 변수를 잘못 이해했을 떄, 이것이 에러로 이어질 가능성이 있는 경우입니다.

profile
iOS & Flutter

0개의 댓글