# 1장 깨끗한 코드

## 코드가 존재하리라

코드는 요구사항을 표현하는 언어

## 나쁜 코드

* 과거에 인기있던 한 프로그램이 제품 출시 주기가 늘어지고, 버그가 많이 생기고, 프로그램 시동 시간이 길어지고 프로그램이 죽는 횟수도 늘어나 고객들이 많이 떠나가고 결국 망했다. 회사가 망한 원인은 **바로 나쁜 코드 탓**이었다.
* 다시 돌아와 나중에 정리하겠다고 다짐했었다.
* 르블랑의 법칙 : `나중은 결코 오지 않는다.`

## 나쁜 코드로 치르는 대가

* 나쁜 코드가 쌓일수록 팀 생산성은 떨어진다. 그러다가 마침내 9에 근접한다.

![나쁜 코드로 계속 작성하는 경우에 보이는 생산성 대 시간 그래프](https://2138471124-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgzD4m5B9DUypSb8OLMPW%2Fuploads%2FikWym3yBYIU34IFeHzCr%2Fimage.png?alt=media\&token=aedfbc4b-9431-419a-88d8-de7369a80002)

### 태도

* 좋은 코드를 사수하는 일은 프로그래머들의 책임이다.
* 나쁜 코드의 위험을 이해하지 못하는 관리자 말을 그대로 따르는 행동은 전문가답지 못하다.

### 원초적 난제

* 기한을 맞추는 유일한 방법(즉, 빨리 가는 유일한 방법)은 언제나 코드를 최대한 깨끗하게 유지하는 습관이다.

## 깨끗한 코드라는 예술?

* 깨끗한 코드와 나쁜 코드를 구분할 줄 안다고 깨끗한 코드를 작성할 줄 안다는 뜻은 아니다.
* 깨끗한 코드를 작성하려면 ‘청결’이라는 힘겹게 습득한 감각을 활용해 자잘한 기법들을 적용하는 절제와 규율이 필요하다. 열쇠는 ‘코드 감각’이다.
* `코드 감각`이 있는 프로그래머는 나쁜 모듈을 보면 좋은 모듈로 개선할 방안을 떠올린다. `코드 감각`으로 최고 방안을 선택한 후 여기서 거기까지 이동하는 경로를 계획한다.

## 깨끗한 코드란?

> 비야네 스트롭스트룹

* `보기에 즐거운` 코드
* 효율적인 코드

  속도도 포함되지만, CPU 자원을 낭비하지 않는 코드도 포함된다.
* 코드를 망치려는 유혹을 주지 않는 코드

  나쁜 코드는 나쁜 코드를 유혹한다. (깨진 창문 이론)

  따라서 유혹하지 않게 애초에 깨끗한 코드를 작성해라
* 철저한 오류를 처리하는 코드

  세세한 사항까지 꼼꼼하게 신경써라

  * 프로그래머들이 대충 넘어가는 부분 : 오류 처리, 메모리 누수, 경쟁 상태, 일관성 없는 명명법
* `한` 가지에 `집중`하는 코드

> 그래디 부치

* 가독성이 좋은 코드

  깨끗한 코드는 잘 쓴 문장처럼 읽힌다.
* 명쾌한 추상화

  코드는 추측이 아니라 사실에 기반해야 한다.

  반드시 필요한 내용만 담아야 한다.

> 데이브 토마스

* 깨끗한 코드는 **다른 사람이 고치기 쉽고** 읽기 쉬운 코드
* 테스트 케이스(단위 테스트, 인수 테스트)가 있는 코드

  **아무리 코드가 우아해도, 아무리 가독성이 높아도, 테스트 케이스가 없으면 깨끗하지 않다.**
* `최소`의 코드

  작을수록 좋다.

> 마이클 페더스

* 누군가 **시간을 들여 깔끔하고 단정하게 정리한** 느낌을 주는 코드

> 론 제프리스

* **모든 테스트를 통과한다.**
* 중복이 없다.
* 시스템 내 모든 설계 아이디어를 표현한다.
* 클래스, 메서드, 함수 등을 최대한 줄인다. → 최소한의 기능만 담으라는 의미인 것 같다.

어떤 집합에서 특정 항목을 찾아낼 필요가 자주 생긴다. 이런 상황이 발생하면 나는 추상 메서드나 추상 클래스를 만들어 실제 구현을 감싼다.

> 워드 커닝햄

* 코드를 읽으면서 짐작했던 기능을 각 루틴이 그대로 수행한다면 깨끗한 코드라 불러도 되겠다.
* 코드가 그 문제를 풀기 위한 언어처럼 보인다면 아름다운 코드라 불러도 되겠다.

## 보이스카우트 규칙

* 적극적으로 코드의 퇴보를 막아야한다.
* 잘 짠 코드가 전부가 아니다. **시간이 지나도 언제나 깨끗하게 유지해야 한다.**

코드를 작성하기 이전의 코드보다 좀 더 깨끗한 코드를 작성한다면 코드는 절대 나빠지지 않는다. 한꺼번에 많은 시간과 노력을 투자해 코드를 정리할 필요가 없다. **변수 이름 하나를 개선하고, 조금 긴 함수 하나를 분할하고, 약간의 중복을 제거하고, 복잡한 if 문 하나를 정리하면 충분하다.**

## 설계 원칙 SOLID

* **SRP(The Single Responsibility Principle)**: 클래스에는 한 가지, 단 한 가지 변경 이유만 존재해야 한다.
* **OCP(The Open Closed Principle)**: 클래스는 확장에 열려 있어야 하며 변경에 닫혀 있어야 한다.
* **LSP(The Liscov Substitution Principle)**: 상속받은 클래스는 기초 클래스를 대체할 수 있어야 한다.
* **DIP(The Dependency Injection Principle)**: 추상화에 의존해야 하며, 구체화에 의존하면 안 된다.
* **ISP(The Interface Segregation Principle)**: 클라이언트에 밀접하게 작게 쪼개진 인터페이스를 유지한다.
