Skip to content

Clean Code로 가독성 높은 코드 작성하는 법 ​

로버트 C. 마틴의 Clean Code(클린 코드)를 읽고 매일 아침 코딩하기 전 인덱스를 한번씩 보면서 되새김질 하기 위해 목차와 느낀점을 간단하게 적어본다. 팀 리더, 팀원들에게 종종 피드백 받는 부분이 이 책에서 잘 설명해주어 왜 그래야했는지 납득되었다.

오늘도 클코하자~~

1장 깨끗한 코드 ​

코드가 존재하리라

나쁜 코드

나쁜 코드로 치르는 대가

  • 원대한 재설계의 꿈
  • 태도
  • 원초적 난제
  • 깨끗한 코드라는 예술?
  • 깨끗한 코드란?

우리들 생각

우리는 저자다

보이스카우트 규칙

프리퀄과 원칙

결론

참고 문헌

2장 의미 있는 이름 ​

들어가면서

의도를 분명히 밝혀라

그릇된 정보를 피하라

의미 있게 구분하라

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

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

인코딩을 피하라

  • 헝가리식 표기법
  • 멤버 변수 접두어
  • 인터페이스 클래스와 구현 클래스

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

클래스 이름

메서드 이름

기발한 이름은 피하라

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

말장난을 하지 마라

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

문제 영역에서 가져온 이름을 사용하라

의미 있는 맥락을 추가하라

불필요한 맥락을 없애라

마치면서

3장 함수 ​

작게 만들어라!

  • 블록과 들여쓰기

한 가지만 해라!

  • 함수 내 섹션

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

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

Switch 문

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

함수 인수

  • 많이 쓰는 단항 형식
  • 플래그 인수
  • 이항 함수
  • 삼항 함수
  • 인수 객체
  • 인수 목록
  • 동사와 키워드

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

  • 출력 인수

명령과 조회를 분리하라!

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

  • Try/Catch 블록 뽑아내기
  • 오류 처리도 한 가지 작업이다.
  • Error.java 의존성 자석

반복하지 마라!

구조적 프로그래밍

함수를 어떻게 짜죠?

결론

참고 문헌

4장 주석 ​

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

코드로 의도를 표현하라!

좋은 주석

  • 법적인 주석
  • 정보를 제공하는 주석
  • 의도를 설명하는 주석
  • 의미를 명료하게 밝히는 주석
  • 결과를 경고하는 주석
  • TODO 주석
  • 중요성을 강조하는 주석
  • 공개 API에서 Javadocs

나쁜 주석

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

참고 문헌

5장 형식 맞추기 ​

형식을 맞추는 목적

적절한 행 길이를 유지하라

  • 신문 기사처럼 작성하라
  • 개념은 빈 행으로 분리하라
  • 세로 밀집도
  • 수직 거리
  • 세로 순서

가로 형식 맞추기

  • 가로 공백과 밀집도
  • 가로 정렬
  • 들여쓰기

가짜 범위

팀 규칙

밥 아저씨의 형식 규칙

6장 객체와 자료 구조 ​

자료 추상화

자료/객체 비대칭

디미터 법칙

  • 기차 충돌
  • 잡종 구조
  • 구조체 감추기

자료 전달 객체

  • 활성 레코드

결론

참고 문헌

7장 오류 처리 ​

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

Try-Catch-Finally 문부터 작성하라

미확인unchecked 예외를 사용하라

예외에 의미를 제공하라

호출자를 고려해 예외 클래스를 정의하라

정상 흐름을 정의하라

null을 반환하지 마라

null을 전달하지 마라

결론

참고문헌

8장 경계 ​

외부 코드 사용하기

경계 살피고 익히기

log4j 익히기

학습 테스트는 공짜 이상이다

아직 존재하지 않는 코드를 사용하기

깨끗한 경계

참고 문헌

9장 단위 테스트 ​

TDD 법칙 세 가지

깨끗한 테스트 코드 유지하기

  • 테스트는 유연성, 유지보수성, 재사용성을 제공한다

깨끗한 테스트 코드

  • 도메인에 특화된 테스트 언어
  • 이중 표준

테스트 당 assert 하나

  • 테스트 당 개념 하나

F.I.R.S.T.

결론

참고 문헌

10장 클래스 ​

클래스 체계

  • 캡슐화

클래스는 작아야 한다!

  • 단일 책임 원칙
  • 응집도Cohesion
  • 응집도를 유지하면 작은 클래스 여럿이 나온다

변경하기 쉬운 클래스

  • 변경으로부터 격리

참고 문헌

11장 시스템 ​

도시를 세운다면?

시스템 제작과 시스템 사용을 분리하라

  • Main 분리
  • 팩토리
  • 의존성 주입

확장

  • 횡단(cross-cutting) 관심사

자바 프록시

순수 자바 AOP 프레임워크

AspectJ 관점

테스트 주도 시스템 아키텍처 구축

의사 결정을 최적화하라

명백한 가치가 있을 때 표준을 현명하게 사용하라

시스템은 도메인 특화 언어가 필요하다

결론

참고 문헌

12장 창발성(創發性) ​

창발적 설계로 깔끔한 코드를 구현하자

단순한 설계 규칙 1: 모든 테스트를 실행하라

단순한 설계 규칙 2~4: 리팩터링

중복을 없애라

표현하라

클래스와 메서드 수를 최소로 줄여라

결론

참고 문헌

13장 동시성 ​

동시성이 필요한 이유?

  • 미신과 오해

난관

동시성 방어 원칙

  • 단일 책임 원칙Single Responsibility Principle, SRP
  • 따름 정리corollary: 자료 범위를 제한하라
  • 따름 정리: 자료 사본을 사용하라
  • 따름 정리: 스레드는 가능한 독립적으로 구현하라

라이브러리를 이해하라

  • 스레드 환경에 안전한 컬렉션

실행 모델을 이해하라

  • 생산자-소비자Producer-Consumer
  • 읽기-쓰기Readers-Writers
  • 식사하는 철학자들Dining Philosophers

동기화하는 메서드 사이에 존재하는 의존성을 이해하라

동기화하는 부분을 작게 만들어라

올바른 종료 코드는 구현하기 어렵다

스레드 코드 테스트하기

  • 말이 안 되는 실패는 잠정적인 스레드 문제로 취급하라
  • 다중 스레드를 고려하지 않은 순차 코드부터 제대로 돌게 만들자
  • 다중 스레드를 쓰는 코드 부분을 다양한 환경에 쉽게 끼워 넣을 수 있게 스레드 코드를

구현하라

  • 다중 스레드를 쓰는 코드 부분을 상황에 맞게 조율할 수 있게 작성하라
  • 프로세서 수보다 많은 스레드를 돌려보라
  • 다른 플랫폼에서 돌려보라
  • 코드에 보조 코드instrument를 넣어 돌려라. 강제로 실패를 일으키게 해보라
  • 직접 구현하기
  • 자동화

결론

참고 문헌

14장 점진적인 개선 ​

Args 구현

  • 어떻게 짰느냐고?

Args: 1차 초안

  • 그래서 멈췄다
  • 점진적으로 개선하다

String 인수

결론

15장 JUnit 들여다보기 ​

JUnit 프레임워크

결론

16장 SerialDate 리팩터링 ​

첫째, 돌려보자

둘째, 고쳐보자

결론

참고 문헌

17장 냄새와 휴리스틱 ​

주석

  • C1: 부적절한 정보
  • C2: 쓸모 없는 주석
  • C3: 중복된 주석
  • C4: 성의 없는 주석
  • C5: 주석 처리된 코드

환경

  • E1: 여러 단계로 빌드해야 한다
  • E2: 여러 단계로 테스트해야 한다

함수

  • F1: 너무 많은 인수
  • F2: 출력 인수
  • F3: 플래그 인수
  • F4: 죽은 함수

일반

  • G1: 한 소스 파일에 여러 언어를 사용한다
  • G2: 당연한 동작을 구현하지 않는다
  • G3: 경계를 올바로 처리하지 않는다
  • G4: 안전 절차 무시
  • G5: 중복
  • G6: 추상화 수준이 올바르지 못하다
  • G7: 기초 클래스가 파생 클래스에 의존한다
  • G8: 과도한 정보
  • G9: 죽은 코드
  • G10: 수직 분리
  • G11: 일관성 부족
  • G12: 잡동사니
  • G13: 인위적 결합
  • G14: 기능 욕심
  • G15: 선택자 인수
  • G16: 모호한 의도
  • G17: 잘못 지운 책임
  • G18: 부적절한 static 함수
  • G19: 서술적 변수
  • G20: 이름과 기능이 일치하는 함수
  • G21: 알고리즘을 이해하라
  • G22: 논리적 의존성은 물리적으로 드러내라
  • G23: If/Else 혹은 Switch/Case 문보다 다형성을 사용하라
  • G24: 표준 표기법을 따르라
  • G25: 매직 숫자는 명명된 상수로 교체하라
  • G26: 정확하라
  • G27: 관례보다 구조를 사용하라
  • G28: 조건을 캡슐화하라
  • G29: 부정 조건은 피하라
  • G30: 함수는 한 가지만 해야 한다
  • G31: 숨겨진 시간적인 결합
  • G32: 일관성을 유지하라
  • G33: 경계 조건을 캡슐화하라
  • G34: 함수는 추상화 수준을 한 단계만 내려가야 한다
  • G35: 설정 정보는 최상위 단계에 둬라
  • G36: 추이적 탐색을 피하라

자바

  • J1: 긴 import 목록을 피하고 와일드카드를 사용하라
  • J2: 상수는 상속하지 않는다
  • J3: 상수 대 Enum

이름

  • N1: 서술적인 이름을 사용하라
  • N2: 적절한 추상화 수준에서 이름을 선택하라
  • N3: 가능하다면 표준 명명법을 사용하
  • N4: 명확한 이름
  • N5: 긴 범위는 긴 이름을 사용하라
  • N6: 인코딩을 피하라
  • N7: 이름으로 부수 효과를 설명하라

테스트

  • T1: 불충분한 테스트
  • T2: 커버리지 도구를 사용하라!
  • T3: 사소한 테스트를 건너뛰지 마라
  • T4: 무시한 테스트는 모호함을 뜻한다
  • T5: 경계 조건을 테스트하라
  • T6: 버그 주변은 철저히 테스트하라
  • T7: 실패 패턴을 살펴라
  • T8: 테스트 커버리지 패턴을 살펴라
  • T9: 테스트는 빨라야 한다

결론

참고 문헌

부록A 동시성 II ​

클라이언트/서버 예제

  • 서버
  • 스레드 추가하기
  • 서버 살펴보기
  • 결론

가능한 실행 경로

  • 경로 수
  • 가능한 순열 수 계산하기
  • 심층 분석
  • 결론

라이브러리를 이해하라

  • Executor 프레임워크
  • 스레드를 차단하지 않는non blocking 방법
  • 다중 스레드 환경에서 안전하지 않은 클래스

메서드 사이에 존재하는 의존성을 조심하라

  • 실패를 용인한다
  • 클라이언트-기반 잠금
  • 서버-기반 잠금

작업 처리량 높이기

  • 작업 처리량 계산 - 단일스레드 환경
  • 작업 처리량 계산 - 다중 스레드 환경

데드락

  • 상호 배제Mutual Exclusion
  • 잠금 & 대기Lock & Wait
  • 선점 불가No Preemption
  • 순환 대기Circular Wait
  • 상호 배제 조건 깨기
  • 잠금 & 대기 조건 깨기
  • 선점 불가 조건 깨기
  • 순환 대기 조건 깨기
  • 다중 스레드 코드 테스트
  • 스레드 코드 테스트를 도와주는 도구

결론

자습서: 전체 코드 예제 ​

  • 클라이언트/서버 - 단일스레드 버전
  • 클라이언트/서버 - 다중 스레드 버전

부록B org.jfree.date.SerialDate ​

부록C 휴리스틱의 교차 참조 목록 ​

에필로그

용어 대역표

약어 목록

찾아보기

Email: echo.youn@kakao.com