카테고리 없음

[CleanCode] 6주차 - 15장, 16장, 17장

Hanee_ 2022. 5. 2. 21:27

15장 JUnit 들여다보기

 

16장 SerialDate 리팩터링

SerialDate는 날짜를 표현하는 자바 클래스! 

예시 설명한거라..패쓰!

 

 

 


17장 냄새와 휴리스틱

✅ 주석

C1. 부적절한 정보

다른 시스템에 저장할 정보는 주석으로 적절하지 못함 주석은 코드와 설계에 기술적 설명을 부연하는 수단

 

C2. 쓸없는 주석

주석은 빨리 낡는다. 쓸모 없어질 주석은 아예 달지 않는 편이 가장 좋음

 

C3. 중복된 주석

코드만으로 충분한데 구구절절 설명하는 주석이 중복된 주석

 

C4. 성의 없는 주석

단어 신중하게 선택하고 당연한 소리 반복하지 않을 것

 

C5. 주석 처리된 코드

주석으로 처리된 코드는 즉각 지워버릴 것

 

✅ 환경

E1. 여러 단계로 빌드해야한다

빌드는 간단히 한 단계로 끝나야함. 온갖 기타 시스템에 필요한 파일을 찾느라 여기저기 뒤적일 필요가 없어야한다. 한 명령으로 전체를 체크아웃해서 빌드할 수 있어야함

 

E2. 여러단계로 테스트해야한다

모든 단위 테스트는 한 명령으로 돌려야한다

 

✅ 함수

F1. 너무 많은 인수

함수에서 인수 개수는 작을 수록 좋다. 아예 없으면 더 좋음

 

F2. 출력 인수

출력 인수는 직관을 정면으로 위배한다. 함수에서 뭔가으 ㅣ상태를 변경해야한다면 함수가 속한 객체의 상태를 변경한다

 

F3. 플래그 인수

boolean인수는 함수가 여러기능을 수행한다는 명백한 증거!. 플래그 인수를 혼란을 초래하므로 피해야 마땅함

 

 F4. 죽은 함수

아무도 호출하지 않는 함수는 삭제

 

✅ 일반

G1. 한 소스 파일에 여러 언어를 사용한다.

이상적으로는 소스파일 하나에 언어 하나만 사용하는 방식이 가장 좋다. 하지만 불가피하므로 소스파일에서 언어 수와 범위를 최대한 줄이도록 해야한다.

 

G2. 당연한 동작을 구현하지 않는다

최소 놀람의 원칙에 의거해 함수나 클래스는 다른 프로그래머가 당연하게 여길만한 동작과 기능을 제공해야함

당연한 동작을 구현하지 않으면 코드를 읽거나 사용하는 사람이 더이상 함수 이름만으로 함수 기능을 직관적으로 예상하기가 어렵다

 

G3. 경계를 올바로 처리하지 않는다

코드는 올바로 동작해야한다. 모든 경계 조건을 찾아내고, 모든 경계 조건을 테스트하는 테스트 케이스를 작성하라

 

G4. 안전 절차 무시

실패하는 테스트 케이스를 제껴두는 태도는 위험하다

 

G5. 중복

코드에서 중복을 발견할 때마다 추상화할 기회로 간주할 것

중복된 코드를 하위 루틴이나 다른 클래스로 분리하라

 

G6. 추상화 수준이 올바르지 못하다

추상화는 저차원 상세 개념에서 고차원 일반 개념을 분리함

우리는 추상 클래스와 파생클래스를 생성해 추상화를 수행한다. 추상화로 개ㅁ념을 분ㄹ할 땐 철저해야한다. 모든 저차원의 개념은 파생 클래스에 넣고, 모든 고차원 개념은 기초 클래스에 넣음

 

G7. 기초 클래스가 파생 클래스에 의존한다.

개념을 기초 클래스와 파생 클래스로 나누는 가장 흔한 이유는 고차원 기초 클래스 개념을 저차원 파생 클래스 개념으로부터 분리해 독립성을 보장하기 위해서다. 따라서 기초클래스가 파생클래스를 사용한다면 문제가 잇음

 

G8. 과도한 정보

잘 정의된 모듈은 인터페이스가 아주 작다. 그래서 간단한 동작 하나에도 온갖 인터페이스가 필요. 잘 정의된 인터페이스는 많은 함수를 제공하지 않는다. 따라서 결합도가 낮음

 

G9. 죽은 코드

죽은 코드란 실행되지 않는 코드 -> 시스템에서 제거할 것

 

G10. 수직분리

변수와 함수는 사용되는 위치에 가깝게 정의

비공개 함수는 처음으로 호출한 직후에 정의

 

G11. 일관성 부족

어떤 개념을 특정 방식으로 구현했다면 유사한 개념도 같은 방식으로 구현

 

G12. 잡동사니

잡동사니 없앨 것

 

G13. 인위적 결합

서로 무관한 개념을 인위적으로 결합하지 않는다. 함수 상수 변수를 선언할 땐 시간을 들여 올바른 위치를 고민할 것

 

G14. 기능 욕심

클래스 메서드는 자기 클래스의 변수와 함수에 관심을 가져야지 다른 클래스의 변수와 함수에 관심을 가져서는 안됨

 

G16. 모호한 의도

코드를 짤 땐 의도를 최대한 분명히 밝힘

 

G18. 부적절한 static 함수

static 함수로 정의할 시 재정의할 가능성은 없는지 따질 것\

 

G19. 서술적 변수

이름만으로 분명하지 않기에 구현을 살피거나 문서를 뒤적여야 한다면 더 좋은 이름으로 바꾸거나 더 좋은 이름을 붙이기 쉽도록 기능을 정리할 것

 

G23. If/Else 혹은 Switch/Case 문보다 다형성을 사용할 것

 

G29. 부정 조건은 피할 것

 

 

if(buffer.shouldNotCompact())

if(buffer.shouldCompact())

 

G33. 경계 조건을 캡슐화 할 것

 

if ( a+1 < tags.length ){
 retun null;
}

number = a+1;
if ( number < tags.length ){
 retun null;
}

 

 

G35. 설정정보는 최상위 단계에 둘 것

그래야 변경하기 쉬움

 

G36. 추이적 탐색을 피하라

한 모듈은 주변 모듈을 모를 수록 좋다

디미터의 법칙

자신이 직접 사용하는 모듈만 알아야 한다. 내가 아는 모듈이 연이어 자신이 아는 모듈을 따라가며 시스템 전체를 휘저을 필요가 없다는 뜻

 

✅ 테스트

T1. 불충분한 테스트 

잠재적으로 깨질만한 부분을 모두 테스트해야함

 

T2. 커버리지 도구 사용할 것

테스트가 빠뜨리는 공백을 알려준다.

커버리지 도구를 사용하면 테스트가 불충분한 모듈, 클래스, 함수를 찾기가 쉬워짐

 

T3. 사소한 테스트를 건너뛰지 말 것

 

T4. 무시한 테스트는 모호함을 뜻함

 

T5. 경계 조건을 테스트할 것

 

T6. 버그 주변은 철저히 테스트하라

버그는 서로 모이는 경향이 있음

 

T7. 실패 패턴을 살펴라

 

T8. 테스트 커버리지 패턴을 살펴라

 

T9. 테스트는 빨라야함