클린코드
취업 전 도서관에서 클린코드를 빌려서 읽어본적이 있었다. 물론 2장 중간에 포기하고 반납을 했었다.
그때는 무슨 소리를 하는 지 이 책은 왜이리 어려운 책인가 하고 바로 반납을 해버렸지만....
그때는 무슨 소리를 하는 지 이 책은 왜이리 어려운 책인가 하고 바로 반납을 해버렸지만....
이번엔 3일만에 읽어버렸다. (물론 저자가 직접 리팩토링하면서 설명하는 부분은 좀 빠르게 읽었다)
작년에 회사 업무시간 전 차곡차곡 읽을 생각으로 산 이후로 방치되었었는데, 이번주에는 조금 시간이 넉넉하여 업무시간을 활용하였다.
지금 읽어보니 정말 쉽게 설명되어있고, 기본적으로 코드를 짤 때 필요한 내용이어서 너무 재미있게 읽었다.
왜 우아한형제 기술블로그에서 이 책의 제목이 자주 언급되는 지에 대해서 조금은 알 것 같았다.
반성도 많이하게 되고, 머리에 꽂히는 것도 많은 책이다.
작년에 회사 업무시간 전 차곡차곡 읽을 생각으로 산 이후로 방치되었었는데, 이번주에는 조금 시간이 넉넉하여 업무시간을 활용하였다.
지금 읽어보니 정말 쉽게 설명되어있고, 기본적으로 코드를 짤 때 필요한 내용이어서 너무 재미있게 읽었다.
왜 우아한형제 기술블로그에서 이 책의 제목이 자주 언급되는 지에 대해서 조금은 알 것 같았다.
반성도 많이하게 되고, 머리에 꽂히는 것도 많은 책이다.
꼭 다시 한번 더 읽으리라~~~ (입사,이직 전 한번 읽으면 엄청 좋을 듯!!)
이 책을 모두 정리한다는 것은 어려울 것 같다. 모든 내용이 중요해보였고, 나에게 필요해 보인다.
밑의 내용은 그냥 읽으면서 체크한 내용을 메모한 것이다.
1장 깨끗한 코드
- 자신이 짠 쓰레기 코드를 보고 나중에 정리하겠다고 다짐하지만, 나중은 결코 오지 않는다.
- 나쁜 코드의 위험을 이해하지 못하는 관리자 말을 그대로 따르는 행동은 전문가답지 못하다.
2장 의미있는 이름
- 의도가 분명하게 이름을 지으라
3장 함수
- 작게 만들어라!
- 함수는 한 가지를 해야한다.
- 인수를 줄이자
- 부수효과를 일으키지 마라!
- 반복하지 마라
- 함수를 작게 만든담녀 간혹 return, break, continue를 여러 차례 사용해도 괜찮다. 오히로 때로는 단일 입/출구 규칙보다 의도를 표현하기 쉬워진다. 반면 goto문은 큰 함수에서만 의미가 있으므로, 작은 함수에서는 피해야만 한다.
- 소프트웨어를 짜는 행위는 여느 글짓기와 비슷하다. 먼서 생각을 기록한 후 읽기 좋게 다듬는다. 초안은 대개 서투르고 어수선하므로 원하는 대로 읽힐 때까지 말을 다듬고 문장을 고치고 문단을 정리한다.
4장 주석
- 코드로 의도를 표현하라 : 코드로 대다수의 의도를 표현할 수 있다. 많은 경우 주석으로 달려는 설명을 함수로 만들어 표현해도 충분하다.
5장 형식 맞추기
- 오늘 구현한 기능이 다음 버전에서 바뀔 확률은 아주 높다. 그런데 오늘 구현한 코드의 가독성은 앞으로 바뀔 코드의 품질에 지대한 영향을 미친다. 오랜 시간이 지나 원래 코드의 흔적을 더 이상 찾아보기 어려울 정도로 코드가 바뀌어도 맨 처음 잡아놓은 구현 스타일과 가독성 수준은 유지보수 용이성과 확장설에 계속 영향을 미친다.
- 변수는 사용하는 위치에 최대한 가까이 선언한다.
6장 객체와 자료구조
- 디미터 법칙 : 모듈은 자신이 조작하는 개체의 속사정을 몰라야 한다. 객체는 조회 함수로 내부 구조를 공개하면 안된다.
- 시스템을 구현할 떼, 새로운 자료 타입을 추가하는 유연성이 필요하면 객체가 더 적절하다. 다른 경우로 새로운 동작을 추가하는 유연성이 필요하면 자료구조와 절차적인 코드가 더 적합하다. 우수한 소프트웨어 개발자는 편견없이 이 사실을 이해해 직면한 문제에 최적인 해결책을 선택한다.
7장 오류 처리
- null을 반환하지 마라 : null을 반환하는 코드는 일거리를 늘릴 뿐만 아니라 호출자에게 문제를 떠넘긴다. 누구 하나라도 null 확인을 빼먹는다면 애플리케이션이 통제 불능에 빠질지도 모르다.
8장 경계
- 외부 패키지를 호출하는 코드를 가능한 줄여 경계를 관리하자. 새로운 클래스로 경계를 감싸거나 아니면 ADAPTER 패턴을 사용해 우리가 원하는 인터페이스를 패키지가 제공하는 인터페이스로 변환하자. 어느 방법이든 코드 가독성이 높아지며, 경계 인터페이스를 사용하는 일관성도 높아지며, 외부 패키지가 변했을 때 변경할 코드도 줄어든다.
9장 단위 테스트
- 테스트는 유연성, 유지보수성, 재사용성을 제공한다.
- F.I.R.S.T : 꺠끗한 테스트는 다음 다섯가지 규칙을 따른다.
- Fast 빠르게 : 테스트는 빨리 돌아야한다.
- Independent 독립적으로 : 각 테스트는 서로 의존하면 안된다.
- Repeatable 반복가능하게 : 테스트는 어떤 환경에서도 반복 가능해야한다.
- Self-Validating 자가검증하는 : 테스트는 성공아니면 실패라고 결과를 내야한다. (성공여부루를 알려고 로그를 읽게 만들어선 안된다.)
- Timely 적시에 : 테스트는 적시에 작성해야한다.
10장 클래스
- 클래스 체계 : 표준 자바 관례에 따르면, 가장 먼저 변수 목록이 나온다. static public 상수가 있다면 맨 처음에 나온다. 다음으로 정적 private 변수가 나오며, 이어서 비공개 인스턴스 변수가 나온다. 변수 목록 다음에는 공개 함수가 나온다. 비공개 함수는 자신을 호출하는 공개 함수 직후에 넣는다. 즉, 추상화 단계가 순차적으로 내려간다. 그래서 프로그래램은 신문기사처럼 읽힌다.
- 단일 책임 원칙(SRP) : 클래스는 책임, 즉 변경할 이유가 하나여야 한다.
- 규모가 어느 수준에 이르는 시스템은 논리가 많고도 복잡합하다. 이런 복잡성을 다루려면 체계적인 정리가 필수다. 그래야 변경을 가할 때 직접 영향이 미치는 컴포넌트만 이해해도 충분하다.
- 큰 클래스 몇 개가 아니라 작은 클래스 여럿으로 이뤄진 시스템이 더 바람직하다.
- 시스템의 결합도를 낮추면 유연성과 재사용성도 더 높아진다. 결합도가 낮다는 소리는 각 시스템 요소가 다른 요소로부터 그리고 변경으로부터 잘 격리되어 있다는 의미다.
11장 시스템
- 의존성 주입 : 사용과 제작을 분리하는 강력한 메커니즘. 의존성 주입은 제어의 역전 기법을 의존성관리에 적용한 메커니즘이다. 제어 역전에서는 한 객체가 맡은 보조 책임을 새로운 객체에게 전적으로 떠넘긴다. 새로운 객체는 넘겨받은 책임만 맡으므로 딘일 첵임 원칙을 지키게 된다. 의존성 관리 맥락에서는 객체는 의존성 자체를 인스턴스로 만드는 책임을 지지 않는다. 대신에 이런 책임을 다른 '전담' 메커니즘에 넘겨야만 한다. 그렇게 함으로 써 제어를 역전한다.
- AOP에서 관점이라는 모듈 구성 개념은 "특정 관심사를 지원하려면 시스템에서 특정 지점들이 동작하는 방식을 일관성 있게 바꿔야한다" 라고 명시한다. 프로그래머는 영속석으로 저장할 객체와 속성을 선언한 후 영속성 책임을 영속성 프레임워크에 위임한다. 그러면 AOP 프레임워크는 대상 코드에 영향을 미치지 않는 상태로 동작방식을 변경한다.
- 프로그래머는 설정파일이나 API를 사용해 피룻적인 애플리케이션 기반구조를 구현한다. 여기에는 영속성, 트랜잭션, 보안, 캐시, 장애조치 등과 같은 횡단관심사도 포함된다.
- 시스템을 설계하든 개별 모듈을 설계하든, 실제로는 돌아가는 가장 단순한 수단을 사용해야 한다는 사실을 명심하자.
12장 창발성
- 단순한 설계 규칙 네 가지
- 모든 테스트를 실행한다.
- 중복을 없앤디.
- 프로그래머 의도를 표현한다.
- 클래스와 메서드 수를 최소로 줄인다.
13장 동시성
- 동시성 코드가 일으키는 문제로부터 시스템을 방어하는 원칙과 기술
- 단일 책임 원칙 : 동시성 코드는 다른 코드와 분리하라
- 자료범위를 제한하라 : 자료를 캡슐화하라. 공유 자료를 최대한 줄여라.
- 자료 사본을 사용하라
- 스레드는 가능한 독립적으로 구현하라 : 독자적인 스레드로, 가능하면 다른 프로세서에서, 돌려도 괜찮도록 자료를 독립적인 단위로 분할하라.
- 자바에서 synchronized 키워드를 사용하면 락을 설정한다. 락은 스레드를 지연시키고 부하를 가중시킨다. 그로므로 synchronized 문을 남발하는 코드를 바람하지 않다. 반면, 임계영역은 반드시 보호해야한다. : 동기화하는 부분을 최대한 작게 만들어라
- 스레드 코드 테스트하기 : 문제를 노출하는 테스트 케이스를 작성하라. 프로그램 설정과 시스템 설정과 부하를 바꿔가며 자주 돌려리. 테스트가 실패하면 원인을 추적하라. 다시 돌렸더니 통과하더라는 이유로 그냥 넘어가면 절대 안된다.
14장 점진적인 개선
- 깨끗한 코드를 짜려면 먼저 지저분한 코드를 짠 뒤에 정리해야 한다.
15장 JUnit 들여다보기
16장 SerialDate 리팩터링
17장 냄새와 휴리스틱
- 저자가 코드를 짜면서 사용하는 기교와 휴리스틱을 나열해놓았다. 꼭 다시 한번 볼 것!!
- 주석
- 부적절한 정보
- 쓸모 없는 주석
- 중복된 주석
- 성의 없는 주석
- 주석 처리 된 코드
- 환경
- 여러 단계로 빌드해야 한다
- 여러 단계로 테스트해야 한다
- 함수
- 너무 많은 인수
- 출력 인수
- 플래그 인수
- 죽은 함수
- 일반
- 힌 소스 파일에 여러 언어를 사용한다
- 당연한 동작을 구현하지 않는다
- 경계를 올바로 처리하지 않는다
- 안전 절차 무시
- 중복
- 추상화 수준이 올바르지 못하다
- 기초 클래스가 파생클래스에 의존한다
- 과도한 정보
- 죽은 코드
- 수직 분리
- 일관성 부족
- 잡동사니
- 인위적 결합
- 기능 욕심
- 선택자 인수
- 모호한 의도
- 잘못 지운 책임
- 부적절한 static 함수
- 서술적 변수
- 알고리즘을 이해하라
- If/Else 혹은 Switch/Case 문보다 다형성을 사용하라
- 표준 표기법을 따르라
- 매직 숫자는 명명된 상수로 교체하라
- 정확하라
- 관례보다 구조를 사용해라
- 조건을 캡슐화하라
- 부정 조건을 피하라
- 함수는 한 가지만 해야한다
- 일관성을 유지하라
- 경계조건을 캡슐화하라
- 설정 정보는 최상위 단계에 둬라
- 추이적 탐색을 피하라
- 자바
- 긴 Import 목록을 피하고 와일드 카드를 사용하라
- 상수는 상속하지 않는다
- 상수 대신 Enum
- 이름
- 서술적인 이름을 사용하라
- 적절한 추상화 수준에서 일므을 선택하라
- 가능하다면 표준 명명법을 사용하라
- 긴 범위는 긴 이름을 사용하라
- 인코딩을 피하라
- 이름으로 부수 효과를 설명하라
- 테스트
- 불충분한 테스트
- 커버리지 도구를 사용하라
- 사소한 테스트를 건너뛰지 마라
- 무시한 테스트는 모호함을 뜻한다
- 경계조건을 테스트하라
- 버그 주변은 철저히 테스트하라
- 실패 패턴을 살펴라
- 테스트 커버리지 패턴을 살펴라
- 테스트는 빨라야 한다