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

The art of readable code ch4 ch8

Embed Size (px)

DESCRIPTION

Seminar material of The art of readable code chapter 4 - chapter 8

Citation preview

Page 1: The art of readable code ch4   ch8

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

Page 2: The art of readable code ch4   ch8

주석에 담아야 하는 대상

명확하고 간결한 주석 달기

읽기 쉽게 흐름제어 만들기

거대한 표현을 잘게 쪼개기

목차

Page 3: The art of readable code ch4   ch8

주석에 담아야 하는 대상

주석에 담아야 하는 대상

코드를 읽는 사람이 코드를 작성한 사람만큼 코드를 잘 이해할 수 있게 도울 수 있어야 한다.

우리는 코드를 작성할 때 머릿속에 귀중한 정보가 있다.

그런데 다른 사람이 그 코드를 보면 그런 귀중한 정보는 없다.

그들이 가진 정보라곤 눈앞에 있는 코드뿐이기에

Page 4: The art of readable code ch4   ch8

주석에 담아야 하는 대상

설명하지 말아야 하는 것

코드를 더 잘 이해할 수 있도록 도와주지 않으므로 위 주석들은 가치가 없다. 코드에서 빠르게 유추할 수 있는 내용은 주석을 달지 말자.

Page 5: The art of readable code ch4   ch8

주석에 담아야 하는 대상

설명하지 말아야 하는 것

이 주석도 새로운 정보가 없다. 코드만 읽어도 무슨 일을 수행할 수 있는지 알 수 있기 때문이다.

Page 6: The art of readable code ch4   ch8

주석에 담아야 하는 대상

설명 자체를 위한 설명을 달지 말라

이 주석은 함수의 선언과 주석 내용이 일치하다. 그러므로 ‘가치가 없는 주석’이다.

이 함수를 위한 주석을 달고 싶으면 더 중요한 세부사항을 적는 것이 낫다.

Page 7: The art of readable code ch4   ch8

주석에 담아야 하는 대상

나쁜 이름에 주석을 달지말라 - 대신 이름을 고쳐라

이 주석은 ‘clean’이 의미하는 바를 설명하는 것 같다. 나쁜 이름에 대한 변명이다.

애초에 ‘한계를 적용한다’라는 부분은 함수명에 포함했어야 했다. 좋은 이름은 함수가 사용되는 모든 곳에서 드러나므로 좋은 주석보다 낫다.

Page 8: The art of readable code ch4   ch8

주석에 담아야 하는 대상

나쁜 이름에 주석을 달지말라 - 대신 이름을 고쳐라

이 함수명은 뭔가 레지스트리를 삭제하는 위험한 일을 하는 것 처럼 보인다. 하지만 주석이 이런 의심을 완화시키려고 작성되었다.

그냥 함수명 자체로 정확한 설명을 하는 것이 낫다.

Page 9: The art of readable code ch4   ch8

주석에 담아야 하는 대상

코드가 가진 나쁜 가독성을 메우려고 노력하는 ‘애쓰는 주석’ 보단, 함수의 좋은 이름으로 주석없이 설명하는 것이 낫다.

좋은코드 > 나쁜코드 + 좋은주석

Page 10: The art of readable code ch4   ch8

주석에 담아야 하는 대상

생각을 기록하라이제 주석으로 무엇을 설명해야 할까?

좋은 주석은 단순히 ‘자신의 생각’을 기록하는 것만으로도 탄생한다.

이 주석은 코드를 읽는 사람에게 코드 최적화에 시간을 허비하지 않게 도와준다. (나름 해석: 코드는 구린데 놀랍게도 기대이상의 성능을 보여주는 코드라서…)

Page 11: The art of readable code ch4   ch8

주석에 담아야 하는 대상

생각을 기록하라

이 주석이 없으면 뭔가 버그가 있다고 생각할 수 있다. 그래서 테스트 케이스를 짜거나, 버그를 수정하는데 시간을 허비할지도 모른다.

코드가 엉망이라는 사실을 밝히고, 어떻게 수정해야 하는지 알려준다. 이 주석이 없다면 많은 사람이 이 코드에 겁을 먹고 건드리지 않으려고 할 것이다.

Page 12: The art of readable code ch4   ch8

주석에 담아야 하는 대상

코드에 있는 결함을 설명하라코드는 지속적으로 진화하며, 그러는 과정중에 버그를 갖게 될 수 밖에 없다.

이러한 결함을 설명하는 것을 부끄러워 하지말자.

개선이 필요할 때

개선의 아이디어

Page 13: The art of readable code ch4   ch8

주석에 담아야 하는 대상

코드에 있는 결함을 설명하라

팀내 약속에 따라 TODO: 는 반드시 해결해야 하는 중요문제에만 사용할 수도 있다. 중요하지 않은 문제는 (소문자) todo: 혹은 maybe-later: 와 같은 표시를 할 수 있다.

Page 14: The art of readable code ch4   ch8

주석에 담아야 하는 대상

상수에 대한 설명상수를 정의할 때는 종종 그 상수가 무엇을 하는지,

그것이 왜 특정한 값을 갖게 되는지 ‘사연’이 존재하기 마련이다.

별도의 설명이 필요할 것 같지 않아 보인다.

그러나 이 상수값을 선택한 사람은 분명 뭔가 더 많은 사실이 알고 있을 수 있다. 이 코드를 읽는 사람은 상수값을 어떻게 변경해야 하는지 알게 되었다.

Page 15: The art of readable code ch4   ch8

주석에 담아야 하는 대상

상수에 대한 설명

상수의 특정한 값이 의미 없는 경우도 있다. 이러한 사실을 알려주는 주석도 유용하다.

상수값이 신중하게 설정되었으므로 변경하지 않는게 더 좋은 경우

변수 이름이 매우 명확하므로 주석이 필요 없다.

Page 16: The art of readable code ch4   ch8

주석에 담아야 하는 대상

나올 것 같은 질문 예측하기

나올 것 같은 질문을 예측하고,

언어가 가지고 있는 특유의 상황에 따라 질문을 예측해서 쉽게 빠질 것 같은 함정을 경고하자.

Page 17: The art of readable code ch4   ch8

주석에 담아야 하는 대상

나올 것 같은 질문 예측하기

이 함수를 구현하려면 외부 이메일 서비스에 접속해야하고, 이 작업이 1초이상 걸릴 수도 있으며,

설상가상으로 사용하다가는 이메일 서비스가 다운될수도 있을지 모른다.

함수의 세부사항을 설명하는 주석으로 실수를 예방할 때 좋다.

Page 18: The art of readable code ch4   ch8

주석에 담아야 하는 대상

나올 것 같은 질문 예측하기

이 함수는 겹겹으로 중첩되었는데 짝이 맞지 않는 태그가 있다면, 엄청난 시간을 허비한다는 함정이 도사리고 있다.

동작하는데 몇 분을 잡아먹을 수 있다.

이러한 단점을 스스로 깨닫기 하기 보다는 주석으로 미리미리 알려주는 것이 좋다.

Page 19: The art of readable code ch4   ch8

주석에 담아야 하는 대상

‘큰 그림’에 대한 주석팀에 새롭게 합류한 사람들은 ‘큰 그림’을 이해하는데에 어려움을 겪는다.

클래스들이 어떻게 상호작용하고, 전체 시스템에서 데이터가 어떻게 흘러다니고,

출발점이 어디인지 파악해야 한다.

“비즈니스 로직과 데이터 베이스를 연결해주는 코드입니다. 애플리케이션 코드에서는 직접 이용하면 안됩니다.”

!“이 클래스는 복잡하게 보이지만, 사실 스마트 캐시에 불과합니다.

시스템의 다른 부분은 전혀모르는 코드에요.”

앞서 설명한 말은 바로 상위수준 주석에 포함되어야 하는 내용이다.

Page 20: The art of readable code ch4   ch8

주석에 담아야 하는 대상

‘큰 그림’에 대한 주석

앞서 이야기한 파일수준 주석에 있어야 하는 설명의 예

상세하고 공식적인 문서를 작성해야 한다는 생각에 압도당하지 말자. 잘 선택된 몇몇 문장이 아무것도 없는 것보단 훨씬 나은 법이다.

Page 21: The art of readable code ch4   ch8

주석에 담아야 하는 대상

요약 주석

주석없이 코드를 한줄씩 읽는다는 것은 미스터리물을 읽는 행위나 다름없다. 하위수준 코드의 내용을 간결하게 요약하는 주석의 예.

이 주석은 커다란 ‘덩어리’로 구성된 긴 함수에 특히 유용하며, 함수가 수행하는 기능의 글머리 요약 역할을 수행한다.

Page 22: The art of readable code ch4   ch8

주석에 담아야 하는 대상

마지막 고찰 - 글 쓰는 두려움을 떨쳐내라좋은 주석을 창작하기 위해서 시간을 들이는 것을 아깝게 생각할 수도 있다.

‘글 쓰는 두려움’이 길을 가로 막기 시작했다면, 해결책은 그냥 쓰기 시작하는 것 뿐이다.

일단 생각나는데로 주석을 작성하고,

내용들을 다듬어서 위와 같이 주석의 내용을 개선하면 된다.

• ‘이런 제길’은 주의: 주의를 기울어야 할 내용을 의미 • ‘이건’이라는 표현은 ‘입력을 다루는 코드’를 의미 • ‘복잡해지잖아’라는 표현은 ‘구현하기 어려워진다’를 의미

Page 23: The art of readable code ch4   ch8

주석에 담아야 하는 대상

요약설명하지 말아야 하는 것.

코드 자체에서 재빨리 도출될 수 있는 것 나쁜 함수명과 같이 나쁘게 작성된 코드를 보정하려고 애쓰는 주석.

그렇게 하는 대신 코드를 수정하라.

기록해야 하는 생각코드가 특정한 방식으로 작성한 이유를 설명해주는 내용 코드에 담긴 결함. TODO: 혹은 XXX:와 같은 표시를 사용

어떤 상수가 특정한 값을 갖게 된 이유

코드를 읽는 입장이 되기코드를 읽는 사람이 자기가 작성한 코드의 어느 부분을 보고 ‘뭐라고?’라는 생각을 할지 예측하고 주석에 추가

평범한 사람이 예상하지 못할 특이한 동작을 기록 파일이나 클래스 수준 주석에서 ‘큰 그림’을 설명하고 각 조각이 어떻게 맞춰지는지 설명

코드에 블록별로 주석을 달아 세부 코드를 읽다가 나무만 보고 숲을 못 보는 실수를 저지르지 마라

Page 24: The art of readable code ch4   ch8

명확하고 간결한 주석 달기

명확하고 간결한 주석 달기

주석은 명확하게, 최대한 구체적이고 자세하게 작성해야 한다.

주석은 화면에서 면적을 최대한 차지하지 않아야 하며,

읽는데 시간을 요구하므로 최대한 간결해야 한다.

Page 25: The art of readable code ch4   ch8

주석을 간결하게 하라‘정보 대 공간’ 비율을 갖추는 법

명확하고 간결한 주석 달기

Page 26: The art of readable code ch4   ch8

모호한 대명사는 피하라코드를 읽는 사람이 대명사를 ‘해석’하려면 노력이 필요하다.

때로는 ‘it’이나 ‘this’가 가리키는 것이 무엇인지 불분명할 때도 있다.

명확하고 간결한 주석 달기

혼동의 여지가 있기 때문에 대명사를 명사로 대체한 주석이다. 이 것을 더 명확하게 하기 위해서 문장을 고칠 수도 있다.

Page 27: The art of readable code ch4   ch8

엉터리 문장을 다듬어라주석을 명확하게 하는 작업과 간결하게 하는 작업은 한번에 이루어진다.

명확하고 간결한 주석 달기

이 문장이 더 간단하고, 짧고, 직설적이다. 아직 방문하지 않은 URL에 높은 우선순위가 부여된다는 사실까지 설명하고 있다.

Page 28: The art of readable code ch4   ch8

함수의 동작을 명확하게 설명하라다음은 줄의 개수를 세는 역할을 하는 함수다.

명확하고 간결한 주석 달기

예전보다 짧아지진 않았지만, 더 많은 정보를 담고 있다. 이 코드를 읽는 사람에게 개행문자가 없으면 0이 반환될 거라는 사실을 알려준다.

그리고, 캐리지 반환문자(\r)는 무시될 거라는 사실도 주석에서 알 수 있다.

Page 29: The art of readable code ch4   ch8

코너케이스를 설명해주는 입/출력 예를 사용하라주석을 작성하는데 신중하게 선택된 “입/출력” 예는 천 마디 말보다 위력적이다.

명확하고 간결한 주석 달기

이 예는 Strip 함수 기능의 전체를 보여준다.

Page 30: The art of readable code ch4   ch8

코너케이스를 설명해주는 입/출력 예를 사용하라입/출력의 다른 예

명확하고 간결한 주석 달기

위 주석은 굉장히 명확하지만 시각적으로 혼란스럽다.

(다음 페이지 설명)

Page 31: The art of readable code ch4   ch8

코너케이스를 설명해주는 입/출력 예를 사용하라

명확하고 간결한 주석 달기

• 벡터 안에 존재하는 값을 pivot으로 사용하여 경계가 분할되는 방식을 설명한다. • 벡터가 중복된 값을 허용한다는 사실을 보여주기 위해서 중복된 값(8)을 포함시켰다. • 중복된 값(8)을 포함시켜 벡터가 중복된 값을 허용한다는 사실을 보여준다. • 결과값을 담은 벡터를 일부러 정렬하지 않았다. 만약 정렬하면 혼동을 초래할 것 이다. • 반환된 값이 1이므로, 벡터에 1이 포함되지 않게 했다. 1이 포함되면 혼동을 초래할 것 이다.

Page 32: The art of readable code ch4   ch8

코드의 의도를 명시하라

명확하고 간결한 주석 달기

코드를 작성하면서 생각했던 바를 나중에 읽는 사람에게 전달해야 한다.

다음은 버그가 있는 코드다. 이미 CompareProductByPrice는 높은 값에서 낮은 값으로 정렬하였다.

이 주석에서 가격을 높은 값에서 낮은 값 순으로 정렬하려는 의도를 파악했고, 이 코드는 실제로 역순으로 반환을 하고 있다.

Page 33: The art of readable code ch4   ch8

코드의 의도를 명시하라

명확하고 간결한 주석 달기

각 가격을 높은 값에서 낮은 값 순으로 나타내야 하는 개발자의 의도를 눈치 챘지만, 내가 보기에는 이 코드는 크기순이 아닌 역순으로 동작하고 있으므로

명백한 버그임을 눈치챌 수 있다.

그래서 주석에 의도를 잘 명시해야 한다.

Page 34: The art of readable code ch4   ch8

이름을 가진 함수 파라미터 주석

명확하고 간결한 주석 달기

이 코드에서 정수와 불리언 값이 무엇을 의미하는지 모른다.

파이썬은 이름을 가진 파라미터가 있기 때문에 주석없이 이해할 수 있다.

C++이나 JAVA같은 언어는 파이썬처럼 할 수 없으니 위와 같은 예시처럼 주석을 사용한다.

Page 35: The art of readable code ch4   ch8

이름을 가진 함수 파라미터 주석

명확하고 간결한 주석 달기

이렇게 하면 곤란하다. 암호화 사용/미사용 의미로 받아들이기 쉽다.

이것도 마찬가지다.

대부분의 함수는 위와 같은 주석이 필요 없는데, 이러한 주석은 뜻이 잘 드러나 있지 않은 인수를 설명하기 위한 간편하고 간결한 방법이다.

Page 36: The art of readable code ch4   ch8

정보 축약형 단어를 사용하라

명확하고 간결한 주석 달기

Page 37: The art of readable code ch4   ch8

정보 축약형 단어를 사용하라

명확하고 간결한 주석 달기

다양한 의미를 함축할 수 있는 단어나 표현들이 많으므로, 프로그래밍에 전형적인 상황을 묘사하는 표현이 있는지 확인해서

정보를 많이 축약하는 것이 좋다.

Page 38: The art of readable code ch4   ch8

요약

‘it’ 이나 ‘this’ 같은 대명사가 여러 가지를 가리킬 수 있다면 사용하지 않는 것이 좋다. 함수의 동작을 실제로 할 수 있는 한도 내에서 최대한 명확하게 설명

신중하게 선택된 입/출력 예로 주석을 서술 코드가 가진 의도를 너무 자세한 내용이 아니라 높은 수준에서 개괄적으로 설명

같은 줄에 있는 주석으로(예. Function(/* arg = */…)의미가 불분명한 함수의 인수를 설명 많은 의미를 함축하는 단어로 주석을 간단하게 만들자

명확하고 간결한 주석 달기

Page 39: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

읽기 쉽게 흐름제어 만들기

이번 장은 코드에 존재하는 흐름제어를 읽기 쉽게 만드는 방법을 논의한다.

조건, 루프, 흐름을 통제하는 선언문이 코드에 없으면 매우 읽기 편하다. 사실 분기문과 점프문은 코드를 복잡하게 만드는 원인이다.

Page 40: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

조건문에서 인수의 순서

왼쪽은 값이 유동적이고 ‘질문을 받는’ 표현 오른쪽은 고정적인 값으로, 비교의 대상으로 사용되는 표현

vs

읽기 좋은 if문의 유용한 규칙

Page 41: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

조건문에서 인수의 순서

vs

bytes_received는 검사를 수행하고자 하는 대상이고, bytes_expected는 더 ‘안정적인’ 값으로 비교에 사용되는 값이다.

“당신의 나이”가 “10”보다 큰가? “10”이 당신의 나이보다 큰가?

!무엇이 제일 자연스러운 것이 생각하면 쉽다.

Page 42: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

if/else 블록의 순서

부정이 아닌 긍정을 먼저 다루자. 간단한 것을 먼저 처리하자.

더 흥미롭고, 확실한 것을 먼저 다루자.

vs

Page 43: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

if/else 블록의 순서

vs

대상이 궁금한지 궁금하지 않는지 먼저 떠올려보자. 흥미롭고 확실한 것을 먼저 다뤄야 하므로

오른쪽의 방법이 가장 좋다.

Page 44: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

삼항연산자(?:)를 이용하는 조건문 표현

vs

삼항 연산자가 읽기 편하고 간결한 경우와 다소 산만하고 중복적인 느낌이 있는 경우다.

Page 45: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

삼항연산자(?:)를 이용하는 조건문 표현

vs

이 경우는 반대로 삼항 연산자 표현이 어지럽고 복잡하다. 이러한 코드는 if문으로 작성하는 편이 자연스럽다.

줄 수를 최소화 하는 일 보다 다른 사람이 코드를 읽고 이해하는 데 걸리는 시간을 최소화 하는 일이 중요하다. 삼항연산은 매우 간단할 때만 사용해야 한다.

Page 46: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

do/while 루프를 피하라

do/while 루프의 do는 적어도 한번 실행된다. 일반적으로 if, while, for 문의 동작원리는 코드를 위에서 아래로 읽는 순서가 있다.

반대로 그 역순인 do/while 문은 부자연 스럽다.

Page 47: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

do/while 루프를 피하라

while 문은 do/while 문과 달리 코드 블록을 보기전에 반복되는 조건을 미리 확인할 수 있으므로,

읽기 쉽다.

Page 48: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

함수 중간에서 반환하기어떤 프로그래머는 하나의 함수에서 반환하는 곳이 여러 곳이면 안된다고 생각한다.

함수 중간에서 반환하는 것은 완전히 허용하는 것이 바람직할 때도 있다.

하지만, 이 함수는 보호장치 없이 구현하면 매우 부자연스러워 진다.

Page 49: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

함수 중간에서 반환하기반환 포인트를 하나만 두려는 건 함수의 끝 부분에서 실행되는 클린업 코드의 호출을 보장하는 의도가 있다.

현대의 언어에는 클린업 코드를 실행시키는 더 정교한 방법을 제공한다.

순수한 C언어엔 반환할 때 특정한 코드를 실행시키는 방법을 제공한다. 반환지점 다음에 위치한 클린코드를 실행하려면,

함수를 리팩토링 하거나 goto cleanup; 과 같은 명령을 신중하게 사용해야 한다.

Page 50: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

악명 높은 gotoC를 제외한 다른 언어에서는 goto를 사용하는 것보다 더 좋은 방법이 있다.

C는 goto를 사용하면 코드가 쉽게 엉망진창이 되어버리고, 코드의 흐름을 따라가기 어렵다.

goto를 사용하는 가장 간단하고, 순진무구한 방법은 함수의 맨 밑바닥에 하나의 exit 포인트만 두는 것이다.

goto가 이동할 수 있는 장소가 여러곳으로 늘어나면, 스파게티 코드가 양산되므로 goto는 피할 수 있다면 피하는게 낫다.

Page 51: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

중첩을 최소화하기

머릿속에 user_result와 permission_result의 결과를 저장한 상태에서 코드를 계속 읽어 나가고, 각각 if의 블록이 끝날 때마다 그에 상응하는 값을 마음속에서 변경해 나가야 한다.

이런 코드는 사실 좋지않지만, 코드를 읽는 사람이 SUCCESS인 경우와 아닌 경우를 계속해서 왔다 갔다 하기 때문이다.

Page 52: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

중첩이 축적되는 방법

원래 코드는 이렇게 간단했다.

하지만 다른 프로그래머가 두 번째의 동작을 집어넣었다.

Page 53: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

함수의 중간에서 반환하여 중첩을 제거하라

이 코드는 두 단계가 아닌 한 단계의 중첩을 가진다. 모든 if 블록은 return 과 함께 끝나기 때문에,

이 코드를 읽는 사람이 마음속에 있는 스택에서 어떤 값을 꺼낼 필요가 없게 되었다.

Page 54: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

루프 내부에 있는 중첩 제거하기중간에 반환하는 기술은 항상 적용할 수 있는게 아니다.

밖으로 빠져나가지 않고, 중간에 반환할 때는 continue를 사용하면 된다.

Page 55: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

루프 내부에 있는 중첩 제거하기

continue문은 혼란스럽게 보일 수 있다. 그래도 루프의 블록들이 각각 독립적이다.

continue는 단지 “이번 반복을 건너뛰어라”를 의미한다는 사실을 쉽게 확인할 수 있다.

Page 56: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

실행 흐름을 따라올 수 있는가?읽기 쉬운 좋은 흐름을 만들기 위해서는

프로그램의 전체 실행 경로를 쉽게 따라갈 수 있게 만드는게 궁극의 목표다. !

하지만 실제로는 ‘뒤에서’ 실행하는 코드의 흐름을 완전히 따라가기 힘든 경우가 있다.

핵심은 이러한 구조가 차지하는 비율이 높지 않아야 한다. 과용하면 코드의 흐름을 파악하는 일이 어려워진다.

Page 57: The art of readable code ch4   ch8

읽기 쉽게 흐름제어 만들기

요약

• 비교 연산 시 변화하는 값은 왼쪽에 놓고, 안정적이거나 고정적인 값은 오른쪽에 놓는다. • if/else 문의 블록 순서는 긍정적이고, 쉽고, 흥미로운 경우는 앞에 놓이는 것이 좋다. • 삼항연산자나 do/while 그리고 goto 같은 프로그래밍 구조는 코드의 가독성을 해친다. 또한, 그런 구조를 대신할 수 있는 방법도 존재하지만, 되도록은 사용하지 않는 것이 좋다.

• 중첩된 코드 블록의 흐름을 따라가려면 집중을 많이 해야 한다. 지나친 중첩을 피하려면 ‘선형적인’ 코드를 추구해야 한다.

• 함수 중간에 반환하면 중첩을 피하고 코드를 더 깔끔하게 작성할 수 있다. 함수의 앞부분에서 ‘보호 구문’으로 간단한 경우를 미리 처리하는 방식도 유용하다.

Page 58: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

거대한 표현을 잘게 쪼개기우리는 보통 한번에 서너개의 ‘일’만 생각할 수 있다고 한다. 즉 코드의 표현이 커지면 커질수록 이해하기 더 어려우므로, 거대한 표현을 더 소화하기 쉽도록 여러 조각으로 나눈다.

Page 59: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

설명 변수커다란 표현을 쪼개는 가장 쉬운 변수는 하위표현을 담을 추가변수를 만드는 것.

추가변수는 하위표현의 의미를 설명하므로 설명변수라고도 한다.

Page 60: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

요약 변수커다란 코드의 덩어리를 짧은 이름을 가진 변수에 넣어서

쉽게 관리하고, 더 쉽게 파악할 수 있도록 한다.

Page 61: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

요약 변수

이 전 코드와 비교해봤을 때, user_owns_document 라는 요약변수가 추가되면서

“이 것이 바로 이 함수에서 생각해야 하는 주된 개념이군” 이라는 생각이 들게 한다.

Page 62: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

드모르간의 법칙 사용하기

1. not (a or b or c) <> (not a) and (not b) and (not c)2. not (a and b and c) <> (not a) or (not b) or (not c)

회로나 논리수업에서 드모르간의 법칙이 등장한다. 동일한 불리언 표현은 다음과 같다.

드모르간의 법칙을 떠올리는게 힘들다면, “Not을 분배하고 And/Or을 바꿔라”만 기억하면 된다.

Page 63: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

쇼트 서킷 논리 오용말기대부분의 프로그래밍 언어에서 불리언 연산은 쇼트 서킷 평가를 수행한다.

if (a || b)에서 a가 참이면 b는 평가하지 않는다. 이는 편리하지만, 복잡한 연산 수행 시 오용될 수 있다.

이 코드는 의미를 이해하기 위해서 손을 멈추고 생각해야 한다.

위 코드와 동일한 일을 수행하고, 한줄이 더 늘었지만 훨씬 이해하기 쉬워졌다.

나중에 위 코드를 읽는 사람으로 하여금 정신적인 장애물을 없앤 셈이 된 것 이다.

Page 64: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

쇼트 서킷 논리 오용말기대부분의 프로그래밍 언어에서 불리언 연산은 쇼트 서킷 평가를 수행한다.

if (a || b)에서 a가 참이면 b는 평가하지 않는다. 이는 편리하지만, 복잡한 연산 수행 시 오용될 수 있다.

이 코드는 의미를 이해하기 위해서 손을 멈추고 생각해야 한다.

위 코드와 동일한 일을 수행하고, 한줄이 더 늘었지만 훨씬 이해하기 쉬워졌다.

나중에 위 코드를 읽는 사람으로 하여금 정신적인 장애물을 없앤 셈이 된 것 이다.

Page 65: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

쇼트 서킷 논리 오용말기영리하게 작성된 코드는 나중에 다른 사람이 읽을 때 종종 혼란을 초래한다.

이 코드도 쇼트 서킷 연산을 깔끔하게 수행할 수 있다.

파이썬, 자바스크립트, 루비 같은 언어는 ‘or’ 연산자가 인수중 하나를 반환한다. (불리언 값으로 변환되지 않지만)

이 코드는 a, b, c 세 값 중에서 첫 번째 ‘참’ 값을 반환하는데 사용할 수 있다.

Page 66: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

예: 복잡한 논리와 씨름하기

다음 코드는 주어진 범위의 양쪽 경계값이 other의 범위에 속하는지 확인하는 OverlapsWith() 함수를 구현하는 한 방법이다.

Page 67: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

예: 복잡한 논리와 씨름하기

코드가 두줄밖에 되지 않지만, 안에서 많은 일이 일어나고 있다.

이는 생각해야 하거나 조건이 너무나 많으므로 버그가 발생할 확률이 높다

Page 68: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

예: 복잡한 논리와 씨름하기

위 코드는 버그가 있는 코드다. [0, 2]가 [2, 4]와 겹친다고 말한다. 사실은 겹치지 않아야 한다.

그래서 위 코드로 버그를 수정했지만, begin/end가 other를 완전히 포함하는 경우를 무시한다.

Page 69: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

예: 복잡한 논리와 씨름하기

한줄의 코드 추가로 버그를 해결했지만, 코드는 걷잡을 수 없이 보기힘들어지게 되었다.

Page 70: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

더 우아한 접근방법 발견하기

이제 여기서 전진을 멈추고, 다른 접근방법을 생각해야 한다. 간단한 문제로부터 시작해서 버그를 잡는 과정에서 비꼬인 논리를 갖게 되었다.

이런 비꼬인 문제의 해결책을 찾으려면 창의력이 필요하고, 똑같은 문제를 ‘반대되는’방법으로 해결할 수 있는지 확인해보는 것 이다.

Page 71: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

더 우아한 접근방법 발견하기

1. 다른 범위가 이 범위 시작보다 전에 끝난다. 2. 다른 범위가 이 범위가 끝난 후에 시작된다.

여기서 OverlapsWith()의 반대는 ‘겹치지 않는 것’이다. 두개의 범위가 서로 겹치지 않는 것을 확인하는 방법에는 두가지의 가능성만 존재하므로,

훨씬 풀기 쉬운 문제로 다가온다.

새롭게 발견한 접근법

Page 72: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

더 우아한 접근방법 발견하기

아까의 코드 보다 훨씬 간단해지고, 읽기 쉬워 졌다. 이렇게 하면 코드를 읽는 사람이 <= 연산자를 정확하게 사용했는지 쉽게 확인 가능하다.

Page 73: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

거대한 구문 나누기

이 코드는 사람의 머리를 강타하는 거대한 구문을 형성한다. 다행히도 많은 부분들이 동일하다.

동일한 부분을 요약 변수로 추출해서 함수의 앞부분에 둘 수 있다.

Page 74: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

거대한 구문 나누기

코드 개선을 통해 다음과 같은 이점을 누렸다.

• 타이핑 실수를 피할 수 있다. 사실 기존 코드의 다섯번째 ‘highlighted’라는 잘못된 철자가 있다. • 코드를 한눈에 훑어보는게 용이하도록 코드의 길이를 조금이라도 더 줄였다. • 클래스명을 변경해야 할 때 한 곳만 바꾸면 된다.

Page 75: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

표현을 단순화하는 다른 창의적인 방법들

이번에도 10초동안 코드를 자세히 살펴보면 완전히 똑같지는 않다.

공통점을 찾으면 위와 같다.

Page 76: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

표현을 단순화하는 다른 창의적인 방법들

Page 77: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

표현을 단순화하는 다른 창의적인 방법들

눈을 어지럽히는 내용을 모두 제거 했으므로, 코드를 다시 읽으면 핵심을 즉시 이해할 수 있다.

각각의 줄이 같은 일을 수행한다는 사실도 매우 명확해졌다.

매크로의 사용은 권장하는 게 아니라는 사실에 유의하자. 매크로는 다소 혼란스럽게 만들기도 하고, 미세한 버그를 낳기 때문에 매크로의 사용을 자제하는 편이다.

Page 78: The art of readable code ch4   ch8

거대한 표현을 잘게 쪼개기

요약

1. 설명 변수 1. 거대한 표현을 작은 조각으로 나눈다. 2. 하위 표현을 간결한 이름으로 대체하여 코드를 문서화 한다. 3. 코드를 읽는 사람이 코드의 핵심 ‘개념’을 파악하는 것을 돕는다.

2. 드모르간의 법칙을 사용하는 것이다.if (!(a && !b))를 if (!a || b)로 다시 쓴다.

3. 복잡한 논리적 조건들을 만나면 항상 해결할 수 있는 것이 아니다. 때로는 문제의 의미를 ‘거꾸로 부정’ 하거나 혹은 의도한 목적의 반대편을 생각해볼 필요가 있다.

4. 개별적인 표현을 잘개 쪼개는 방법은, 커다란 코드의 블록을 쪼개는 데에도 적용될 수 있다. 복잡하게 보이는 논리를 만나면 잘게 쪼개는 일을 두려워 하지 말라.

Page 79: The art of readable code ch4   ch8

감사합니다.