Support/Clean Code

[Clean Code] 7장 ~ 10장까지 내용 요약

개발자 나르 2022. 5. 3. 01:10
반응형

7장 오류 코드

3장에서 말했듯이 오류 코드보다는 예외처리 try~catch~finally 를 사용하는 것이 옳다.

 

오류 코드보다 try~catch~finally를 써야하는 이유

먼저 가장 중요한건 코드의 복잡성이다. 오류 코드는 일일히 조건문을 통해서 오류를 잡아줘야 한다.

하지만 예외를 던지는 코드는 try 블록에 들어가는 코드를 실행하면 어느 시점에서든 실행이 중단된 후 catch 블록으로 넘어갈 수 있어서 조건문을 일일히 안달아줘도 된다. 

그래서 강제로 예외를 일으키는 테스트 케이스를 작성한 후 테스트를 통과하게 코드를 작성하는 방법을 통해

자연스럽게 try 블록의 트랜잭션 범위부터 구현하여 트랜잭션 본질을 유지하기 쉬워진다.

 

예외에 의미를 제공하라

예외를 던질 때는 전후 상황을 충분히 덧붙인다. 그리하여 오류가 발생한 원인과 위치를 찾기가 수월해진다.

 

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

외부 API를 사용할 때는 감싸기 기법을 사용하여 외부 라이브러리와 프로그램 사이에서 의존성이 크게 줄어들게 한다.

그리고 나중에 다른 라이브러리로 갈아타더라도 비용이 적게 발생한다.

또한 외부 API를 호출하는 대신 테스트 코드를 넣어주는 방법으로 프로그램을 테스트하기도 쉬워진다.

마지막으로는 특정 업체가 설계한 API 방식에 발목 잡히지 않는다.

 

null을 반환하지도 전달하지도 마라 (NullPointerException)

조건문을 통해 하나씩 null을 확인하는 코드는 일거리를 늘릴 뿐만 아니라 호출자에게 문제를 떠넘긴다.

누구 하나라도 null 확인을 빼먹는다면 애플리케이션이 통제 불능에 빠질지도 모른다.

 

요약하자면 깨끗한 코드는 읽기도 좋아야 하지만 안정성 또한 높아야 한다.

오류 처리를 프로그램 논리와 분리하면 독립적인 추론이 가능해지며 코드 유지보수성도 크게 높아진다.

 

8장 경계

학습 테스트

외부 코드를 익히거나 통합하기는 어렵다.

학습 테스트는 프로그램에서 사용하려는 방식대로 외부 API를 호출한다.

통제된 환경에서 API를 제대로 이해하는지를 확인하는 셈이다. API를 사용하려는 목적에 초점을 맞췄다.

 

깨끗한 경계

통제가 불가능한 외부 패키지에 의존하는 거보다는 통제가 가능한 우리 코드에 의존하는 편이 좋다.

위에서 말했듯 감싸기 기법을 활용하여 외부 패키지를 감싸서 우리가 원하는 인터페이스를 패키지가 제공하는 인터페이스로 변환하면 코드 가독성이 높아지며, 인터페이스를 사용하는 일관성도 높아지고, 외부 패키지가 변했을 때의 변경할 코드들도 줄어든다.

 

9장 단위 테스트

TDD 법칙

- 실패하는 단위 테스트를 작성할 때까지 실제 코드를 작성하지 않는다.

- 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다.

- 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다.

 

깨끗한 테스트 코드

깨끗한 테스트 코드를 만들려면 가독성이 제일 중요하다. 그럴려면 명료성, 단순성, 풍부한 표현력이 필요하다.

 

이중 표준

컴퓨터 자원과 메모리가 제한적일 가능성이 높다. 하지만 테스트 환경은 자원이 제한적일 가능성이 낮다.

실제 환경에서는 절대로 안 되지만 테스트 환경에서는 전혀 문제없는 방식이 있다.

 

테스트 당 assert 단 하나만 사용해야 한다. 개념 또한 하나만 있어야 한다.

 

F.I.R.S.T

빠르게 Fast : 테스트는 빨리 돌아야 한다.

독립적으로 Independent : 각 테스트는 서로 의존하면 안된다. 한 테스트가 다음 테스트가 실행될 환경을 준비해서는 안 된다. 각 테스트는 독립적으로 그리고 어떤 순서로 실행해도 괜찮아야 한다.

반복가능하게 Repeatable : 테스트는 어떤 환경에서도 반복 가능해야 한다.

자가검증하는 Self-Validating : 테스트는 bool 값으로 결과를 내야 한다. 성공 아니면 실패다. 로그 파일을 읽거나 텍스트 파일 두 개를 수작업으로 비교하게 만들어서도 안된다.

적시에 Timely : 테스트는 적시에 작성해야 한다. 단위 테스트는 테스트하려는 실제 코드를 구현하기 직전에 구현한다.

 

요약하자면 테스트 코드는 실제 코드의 유연성, 유지보수성, 재사용성을 보존하고 강화하기 떄문이다. 그러므로 지속적으로 테스트 코드는 깨끗하게 관리해야한다. 사실 테스트 코드 안짜봐서 이 부분은 잘 이해가 안갔다. 다음에 개인 프로젝트를 해보면서 깨달아야 할 것같다....

 

10장 클래스

클래스 체계

정적 공개 상수가 있다면 맨 처음에 나온다. 다음으로 정적 비공개 변수, 비공개 인스턴스 변수 순서다.

변수 목록 다음에는 공개 함수가 나온다. 비공개 함수는 자신을 호출하는 공개 함수 직후에 넣는다. 즉, 추상화 단계가 순차적으로 내려간다.

 

클래스도 함수와 마찬가지로 작아야 한다.

가장 처음으로 중요한 것은 작명이다. 작명 하나로 이 클래스는 어떤 클래스인지 대략적으로 짐작이 가능하기 때문이다.

 

단일 책임 원칙(Single Responsibility Principle, SRP)

클래스나 모듈을 변경할 이유가 하나, 단 하나뿐이어야 한다는 원칙이다.

그러므로 클래스도 큰 클래스 몇 개가 아니라 작은 클래스 여럿으로 이뤄진 시스템이 더 바람직하다.

작은 클래스는 각자 맡은 책임이 하나며, 변경할 이유가 하나며, 다른 작은 클래스와 협력해 시스템에 필요한 동작을 수행한다.

 

응집도(Cohesion)

클래스는 인스턴스 변수 수가 작아야 한다. 모든 인스턴스 변수를 메서드마다 사용하는 클래스는 응집도가 가장 높다.

응집도는 높으면 높을수록 좋다. 그 이유는 클래스에 속한 메서드와 변수가 서로 의존하며 논리적인 단위로 묶인다는 의미이기 때문이다.

 

OCP(Open-Closed Principle)

클래스는 확장에 개방적이고 수정에 폐쇄적이어야 한다는 원칙

 

결합도(Coupling)

결합도는 낮을수록 좋다. 그 이유는 코드의 유연성과 재사용성이 더욱 높아진다.

각 시스템 요소가 다른 요소로부터 그리고 변경으로부터 잘 격리되어 있다는 의미이다.

 

DIP(Dependency Inversion Principle)

결합도를 최소로 줄이면 또 다른 설계 원칙인 DIP 원칙이다.

상세한 구현이 아니라 추상화에 의존해야 한다는 원칙이다.

 

요약하자면 클래스는 규모는 작을수록 좋고 논리적인 단위로 묶이는 응집도는 높을수록 좋으며 재사용성과 변경을 위해 결합도는 낮아야 한다.

 

책 이름과 저자 링크 : https://book.naver.com/bookdb/book_detail.nhn?bid=7390287

반응형