Chapter 1. 깨끗한 코드

코드가 존재하리라

  • 코드는 요구사항을 상세히 표현하는 수단
  • 프로그래밍은 기계가 실행할 정도로 상세하게 요구사항을 명시하는 작업

나쁜 코드

  • 좋은 코드는 중요하다
  • 나쁜 코드는 프로그램, 나아가 회사를 망하게 할 수도 있다.
  • 급해서… 서두르느라… 제대로 짤 시간이 없어서… 코드를 다듬느라 상사에게 욕 먹을까봐… 지겨워서… 다른 업무가 밀려서…

일단 나쁜 코드를 짜놓고 나중에 정리하겠다고 다짐하는 것은 옳지 않다. 나중은 결코 오지 않는다. (르블랑의 법칙)

나쁜 코드로 치르는 대가

원대한 재설계의 꿈

  • 개발 속도를 크게 떨어뜨린다
  • 팀 생산성이 떨어진다 > 인력 추가 투입 > 새 인력은 기존 시스템에 대한 설계에 조예가 깊지 않다 > 악순환의 반복
  • 시간을 들여 꺠끗한 코드를 만드는 노력이 비용 절감 뿐만 아니라 전문가로서 살아남는 길이다

태도

  • 일정에 쫓기더라도 대다수 관리자는 좋은 코드를 원한다
  • 나쁜 코드의 위험을 이해하지 못하는 관리자 말을 그대로 따르는 행동은 프로그래머답지 못하다

원초적 난재

  • 기한을 맞추려면 나쁜 코드를 양산할 수밖에 없다고 느낀다
  • 진짜 전문가는 그것이 틀렸다는 사실을 잘 안다. 나쁜 코드를 양산하면 기한을 맞추지 못한다
  • 기한을 맞추는 유일한 방법은 언제나 코드를 최대한 깨끗하게 유지하는 습관이다

깨끗한 코드라는 예술?

  • 깨끗한 코드와 나쁜 코드를 구분할 줄 안다고 깨끗한 코드를 작성할 줄 안다는 뜻은 아니다
  • 깨끗한 코드를 작성하려면 자잘한 기법들을 적용하는 절제와 규율, 그리고 ‘코드 감각’이 필요하다
  • ‘코드 감각’이 있는 프로그래머는 나쁜 모듈을 보면 좋은 모듈로 개선할 방안을 떠올리고, 최고 방안을 선택하여 거기까지 이동하는 경로를 계획한다

깨끗한 코드란?

  • 논리가 간단해야 버그가 숨어들지 못한다
  • 의존성을 최대한 줄여야 유지보수가 쉬워진다
  • 성능을 최적으로 유지해야한다
  • 깨끗한 코드는 한 가지를 제대로 한다
  • 깨끗한 코드는 설계자의 의도를 숨기지 않는다. 오히려 명쾌한 추상화와 단순한 제어문으로 가득하다
  • 작성자가 아닌 사람도 읽기 쉽고 고치기 쉽다
  • 단위 테스트 케이스와 인수 테스트 케이스가 존재한다
  • 깨끗한 코드에는 의미 있는 이름이 붙는다
  • 모두를 아우르는 특징이 하나 있다. 언제나 누군가 주의 깊게 짰다는 느낌을 준다
  • 중복을 피하라. 한 기능만 수행하라. 제대로 표현하라. 작게 추상화하라
  • 코드가 그 문제를 풀기 위한 언어처럼 보인다면 아름다운 코드이다

Chapter 2. 의미 있는 이름

의도를 분명히 밝혀라

  • 좋은 이름을 지으려면 시간이 걸리지만 좋은 이름으로 절약하는 시간이 훨씬 더 많다
  • 의도가 드러나는 이름을 사용하면 코드 이해와 변경이 쉬워진다

그릇된 정보를 피하라

  • 실제 데이터가 List가 아닌데 List로 이름을 짓는다면, 프로그래머에게 그릇된 정보를 제공하는 것이다
  • 유사한 개념은 유사한 표기법을 사용한다. 일관성이 떨어지는 표기법은 그릇된 정보다.

의미 있게 구분하라

  • 읽는 사람이 차이를 알도록 이름을 지어라

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

  • 발음하기 어려운 이름은 토론하기도 어렵다

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

  • a나 b, 1, 3 같은 한단어 보단 MAX_STUDENT_COUNT와 같이 검색이 쉬운 이름을 사용하라

인코딩을 피하라

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

클래스 이름

  • 클래스 이름과 객체 이름은 명사나 명사구가 적당

메서드 이름

  • 메서드 이름은 동사나 동사구가 적당

기발한 이름은 피하라

  • 재미나거나 기발한 이름보단 명료한 이름을 선택하라

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

  • INSERT, ADD, APPEND, PUT 등등 같은 개념에 여러 단어를 사용하면 읽는 입장에선 다 다른 뜻으로 받아들일 수 있다.

말장난을 하지 마라

  • 한 단어를 두 가지 목적으로 사용하지 마라

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

  • 모든 이름을 도메인에서 가져오기 보단 해당 개념에 맞는 이름이 가장 적합한 선택이다

문제 영역에서 가져온 이름을 상요하라

  • 우수한 프로그래머와 설계자라면 해법 영역과 문제 영역을 구분할 줄 알아야 한다

의미 있는 맥락을 추가하라

  • 주소 테이블에서 주소 상태값을 표현해주기 위해 단순히 state라는 단어만 쓰기 보다는, addrState와 같이 써주면 맥락상 더 의미 있게 될 수 있다

불필요한 맥락을 없애라

Chapter 3. 함수

작게 만들어라!

블록과 들여쓰기

  • if/else/while 문 등에 들어가는 블록은 한 줄이어야 한다
  • 중첩 구조가 생길만큼 함수가 커져서는 안 된다

한 가지만 해라!

  • 함수는 한 가지를 해야 한다. 그 한 가지를 잘 해야 한다. 그 한 가지만을 해야 한다

함수 당 추상화 수준은 하나로!

위에서 아래로 코드 읽기 : 내려가기 규칙

  • 코드는 위에서 아래로 이야기처럼 읽혀야 좋다

Switch 문

서술적인 이름을 사용하라!

  • 길고 서울적인 이름이 짧고 어려운 이름보다 좋다
  • 모듈 내에서 함수 이름은 같은 문구, 같은 명사, 동사를 사용한다

함수 인수

  • 함수에서 이상적인 인수 개수는 0개(무항)다
  • 3개는 가능한 피하는 편이 좋고 4개 이상은 특별한 이유가 필요햐다

많이 쓰는 단항 형식

  • fileExists(“FileName”)과 같이 인수에 질문을 던지는 경우
  • fileOpen(“FileName”)과 같이 인수를 뭔가로 변환해 결과를 반환하는 경우

플래그 함수

  • 함수로 부울 값을 넘기는 관례는 이 함수가 한꺼번에 여러 가지를 처리한다고 대놓고 말하는 셈이라 끔직하다

이항 함수

  • 인수가 2개인 함수는 1개인 함수보다 이해하기 어렵다
  • 무조건 나쁜건 아니지만 그만큼 위험이 따른다는 사실을 이해하고 가능하면 단항 함수로 바꾸도록 애써야 한다

삼항 함수

  • 순서, 주춤, 무시로 야기되는 문제가 두 배 이상 늘어난다

부수 효과를 일으키지 마라!

  • 부수 효과는 함수에서 한 가지를 하겠다고 약속하고선 남몰래 다른 행위도 하는 것

명령과 조회를 분리하라!

  • 함수는 뭔가를 수행하거나 뭔가에 답하거나 둘 중 하나만 해야 한다. 둘 다 하면 안 된다
  • 객체 상태를 변경하거나 아니면 객체 정보를 반환하거나 둘 중 하나다

오류 코드보다 예외를 사용하라!

  • 명령 함수에서 오류 코드를 반환하는 방식은 명령/조회 분리 규칙을 미묘하게 위반한다
  • 오류 처리도 한 가지 작업이다. 오류를 처리하는 함수는 오류만 처리해야 한다

반복하지 마라!

  • 중복은 코드 길이가 늘어날 뿐 아니라 알고리즘이 변하면 같은 곳을 다 손봐야 한다

구조적 프로그래밍

  • 데이크스트라는 모든 함수와 함수 내 모든 블록에 입구와 출구가 하나만 존재해야 한다고 말했다

함수를 어떻게 짜죠?

  • 코드를 다듬고, 함수를 만들고, 이름을 바꾸고, 중복을 제거하고, 메서드를 줄이고 순서를 바꾼다

Chapter 4. 주석

주석은 나쁜 코드를 보완하지 못한다

  • 표현력이 풍부하고 깔끔하며 주석이 거의 없는 코드가, 복잡하고 어수선하며 주석이 많이 달린 코드보다 훨씬 좋다

코드로 의도를 표현하라!

// 직원에게 복지 혜택을 받을 자격이 있는지 검사한다.
if((employee.flags & HOURLY_FLAG)&&(employee.age > 65))

위 코드보다는

if (employee.isEligibleForFullBenefits())

와 같이 의도를 표현하는 함수로 만들어 쓰는 것이 좋다

좋은 주석

  • 법적인 주석
  • 정보를 제공하는 주석
  • 의도를 설명하는 주석
  • 의도를 명료하게 밝히는 주석
  • 결과를 경고하는 주석
  • TODO 주석
    • TODO 주석은 ‘앞으로 할 일’을 남겨두는 것에 편리하다.
  • 중요성을 강조하는 주석
  • 공개 API에서 Javadocs

나쁜 주석

  • 주절거리는 주석
  • 같은 이야기를 중복하는 주석
  • 오해할 여지가 있는 주석
  • 의무적으로 다는 주석
  • 이력을 기록하는 주석
  • 있으나 마나 한 주석
  • 함수나 변수로 표현할 수 있는 주석
  • 위치를 표시하는 주석
  • 닫는 괄호에 다는 주석
  • 공로를 돌리거나 저자를 표시하는 주석
  • 주석으로 처리한 코드
  • HTML 주석
  • 전역 정보
  • 너무 많은 정보
  • 모호한 관계
  • 함수 헤더

Chapter 5. 형식 맞추기

형식을 맞추는 목적

  • 코드 형식은 의사소통의 일환이다
  • 오늘 구현한 코드의 가독성은 앞으로 바뀔 코드의 품질에 지대한 영향을 미친다

적절한 행 길이를 유지하라

신문 기사처럼 작성하라

  • 이름은 간단하면서도 설명이 가능하게 짓는다
  • 소스 파일 첫 부분은 고차원 개념과 알고리즘을 설명한다
  • 아래로 내려갈수록 의도를 세세하게 묘사한다
  • 마지막에는 가장 저차원 함수와 세부 내역이 나온다

개념은 빈 행으로 분리하라

세로 밀집도

  • 서로 밀접한 코드 행은 세로로 가까이 놓여야 한다

수직 거리

  • 서로 밀접한 개념은 세로로 가까이 둬야 한다
  • 연관성이 깊은 두 개념이 멀리 떨어져 있으면 읽는 사람이 여기저기 다 뒤지게 된다
변수 선언
  • 변수는 사용하는 위치에 최대한 가까이 선언한다
인스턴스 변수
  • 인스턴스 변수는 클래스 맨 처음에 선언한다.
종속 변수
  • 한 함수가 다른 함수를 호출한다면 두 함수는 세로로 가까이 배치한다
개념적 유사성
  • 친화도가 높을수록 코드를 가까이 배치한다

세로 순서

  • 일반적으로 호출되는 함수를 호출하는 함수보다 나중에 배치한다

가로 형식 맞추기

  • 짧은 행을 주로 쓰도록 하자
  • 책의 저자는 120자 정도로 행 길이를 제한하길 권한다

가로 공백과 밀집도

  • 가로로는 공백을 사용해 밀접한 개념과 느슨한 개념을 표현한다

가로 정렬

  • 선언부의 변수 이름이나 할당문의 오른쪽 피연산자를 나란히 정렬
private String str1;
private int    num1;
private long   lng1;

들여 쓰기

  • 범위(scope)로 이뤄진 계층을 표현하기 위해 우리는 코드를 들여쓴다

가짜 범위

  • 빈 while 문이나 for 문은 가능한 피하도록 하고 안 된다면 세미콜론을 새 행에 들여써서 넣어준다

팀 규칙

  • 팀은 한 가지 규칙에 합의해야 한다. 그리고 모든 팀원은 그 규칙에 따라야 한다

출처 : Clean Code (클린 코드,애자일 소프트웨어 장인 정신), 로버트 C. 마틴 저

최종 업데이트 일자 : 2018년 7월 29일 오후 11시 40분