🚩 7장 오류처리
7장에서는 오류처리를 처리를 하는 기법과 고려사항을 소개한다. 사실 과제나 개인 프로젝트를 하는데 오류를 따로 처리한적이 많지 않았던것 같다. 특히나 java 언어를 쓸때 예외처리를 catch, throw과 같은 코드를 종종 배우는 과정에서 사용했던건 기억나는데 실제로 어떤 프로그램을 혼자 만들때는 잘 쓰지 않았다.. 이 장에서도 돌아가기만 하면 되는 방식으로 코드를 작성했던 방식이 자각이 되었다. 너무 시간이 촉박한 상황에서 코딩해야 하는때가 대부분이었다는것과 예외처리를 하는것에 대한 중요성을 크게 못느꼈다는게 요인이 아니었다 싶다. 하지만 실제로 서비스되는 프로그램의 코드를 짜게된다면 예외처리를 깔끔하게 잘하는것이 정말 중요할것같다.
오류를 처리하는 방법
- 명시적으로 많은 오류코드를 나열하지 말고 예외처리하기
: 알고리즘 논리와 오류부분을 분리할수 있어서 좋다. - Try-Catch-Finally 문을 작성하기
- 미확인 예외를 사용하기
: 확인된 예외 방식은 함수 호출과정에서 연쇄적인 수정이 필요할수 있다! 이런 방식이 아니어도 안정적인 소프트웨어를 구현할수 있다. - 예외에 어떤 예외인지 정보 제공하기
- 예외를 클래스로 정의하기
- null 반환,전달하지 말기!
책에서 소개하는 방법 중에 기본적인 프로그램 논리와 오류처리 부분을 분리하여 각각 독자적인 사안으로 해야한다는 점이 인상적이었다. 알고리즘 공부를 할때도 코드의 전체적인 부분에서 알고리즘과 예외를 동시에 같이 작성하곤 했는데 바람직한 방법이 아니었나보다.. 그리고 객체지향 언어를 사용할때 캡슐화하는것을 좀더 연습을 필요하다는 생각이 들었다.
🚩 8장 경계
8장에서는 외부의 코드를 가져와 사용할때 경계를 어떻게 처리하여 깔끔하게 기존의 코드들과 통합하는 방법에 대해 다룬다. 외부 API를 가져와 문제없이 통합하려는 곳에 잘 작동이 될수 있는지 확인하는 과정에 대한 내용이 꽤 흥미로웠다. 내가 작성한 코드가 아닌 코드들을 다같이 작동되도록 통합하는 과정에서 오류가 생겨서 통합이 안되는건 개인 프로젝트가 아닌 이상 많이 겪는 문제라고 생각이 들었기 때문이다. 책에서 직접적으로 경계, 경계 인터페이스에 대한 내용이 없어서 찾아보았더니 다음과 같았다.
0. 경계란?
- 소프트웨어 경계(시스템 경계)란 인터페이스 제공자와 사용자 사이에서 발생하는 입장차이로 인해 문제가 발생할 수 있는 부분(경계)이다.
- 경계 인터페이스란 어떠한 메서드에서 Map, List 와 같은 자료구조를 반환하거나 공개 API 인수로 넘겨서 클라이언트에서 해당 인터페이스를 사용하는 경우이자.
1. 외부코드 사용하기
- 제네릭스를 사용하는 인터페이스의 인스턴스를 인수로 넘기거나 반환값으로 사용하지 않는다.
2. 학습 테스트 사용하기
3. 아직 존재하지 않는 코드 사용하기
- 외부 API가 아직 완성된 형태가 아닐때 자체적으로 인터페이스를 정의하여 구조를 짜고 테스트를 진행하기
4. 깨끗한 경계
- 경계에 위치한 코드는 분리하고, 기대치를 정의하는 테스트 케이스를 작성하기
- 통제 불가능한 외부 패키지가 아니라 통제 가능한 내부 코드에 의존하기
- 외부 패키지를 호출하는 코드를 가능한 줄이기 or 외부 인터페이스를 패키지가 제공하는 인터페이스로 변환하기
🚩 9장 단위 테스트
이번 9장에서는 단위 테스트에 대한 내용을 다룬다. 단위 테스트(Unit Test)는 응용 프로그램에서 테스트 가능한 가장 작은 소프트웨어를 실행하여 예상대로 동작하는지 확인하는 테스트라고 한다. 그리고 실제 코드 못지 않게 테스트 코드의 중요성을 강조한다. 그 이유로는 테스트케이스가 있다면 코드에 유연성, 유지보수성,재사용성을 제공하기 때문이다. 테스트 케이스가 있다면 코드를 변경할때 좀더 안심할수 있다는것이다. 프로그래머스와 같은 알고리즘 공부하는 사이트에서 푼 문제 코드를 제출하면 여러 테스트케이스에 대해 테스트를 하는데 어떤 작은 알고리즘이라도 여러 테스트를 통해 검증하는게 중요한것 같다는 생각이 들었다.
깨끗한 테스트 코드를 위한 고려사항
- 가독성 높이기
- 테스트 자료를 만들고, 테스트 자료를 조작하고, 조작한 결과가 올바른지 확인하기의 구조
- 도메인에 특화된 테스트 언어(DSL)
: API위에 함수와 유틸리티를 구현한 후 그 함수와 유틸리티를 사용하는데, 이 함수와 유틸리티는 테스트 코드에서 사용하는 특수 API가 된다. 즉, 테스트를 구현하는 당사자와 나중에 테스트를 읽어볼 독자를 도와주는 테스트 언어 - 이중 표준
: 테스트 코드는 단순하고 간결하고 표현력이 풍부해야 하지만, 실제 코드만큼 효율적일 필요는 없다. - 테스트 당 assert 하나, 최대한 줄이기
- 테스트 당 개념 하나
: 테스트 함수마다 한 개념만 테스트하기!
깨끗한 테스트가 따르는 5가지 법칙(F.I.R.S.T)
Fast(빠르게) : 테스트는 가능한 빠르게 동작하여 자주 돌릴수 있도록 한다.
Independent(독립적으로) : 각 테스트는 서로 독립적으로 실행할수 있어야 한다.
Repeatable(반복가능하게) : 테스트는 어떤 환경에서도 반복 가능해야 한다.
Self-Validating(자가검증하는) : 테스트는 bool값으로 결과를 내야한다.
Timely(적시에) :테스트는 적시에 작성한다. 단위 테스트는 테스트하려는 실제 코드를 구현하기 직전에 구현한다.
테스트 코드를 작성하는것도 중요하지만, 테스트 코드를 깨끗하게 유지하는것도 중요하다고 한다.
🚩 10장 클래스
10장에서는 코드를 작성하는것보다 조금 더 높은 차원인 깨끗한 클래스 형성 방법에 대해서 다룬다. 고려사항은 다음과 같이 정리해 볼수 있다.
- 클래스 체계는 변수->함수, 공개->비공개 순으로! 가능하면 캡슐화 유지하기!
- 클래스의 크기는 가능하면 작게하기(맡은 책임을 적게하기) 단일책임원칙(Single Responsibility Principle) : 변경할 이유(책임)를 하나를 정하여 클래스 하나 만들기, 큰 만능 클래스X 여러개 작은 클래스(O)
- 클래스 인스턴스 변수를 많이 사용하는 클래스 메서드를 증가시켜 응집도높이기 : 쪼개기 쉬워지고, 응집력을 잃으면 독자적인 클래스로 분리하기
- 리팩터링한 프로그램은 다음과 같은 이유로 리팩터링 하기 전보다 코드 길이가 더 길어질 수 있다. 1) 서술적인 변수 이름 사용 2)주석 목적으로 함수 선언,클래스 선언 3)가독성을 위한 공백 추가 리팩터링 과정: 원래 프로그램의 정확한 동작을 검증하는 테스트 슈트 작성 > 코드를 조금씩 변경하며 리팩 터링>원래 프로그램 목적과 동일한 동작하는지 확인 반복
- 새 기능을 수정하거나 기존 기능을 변경할 때 건드릴 코드를 최소화하기 (by interface 사용하기)
- 구현을 담당하는 클라이언트 클래스는 구현하려는 내용이 바뀔때마다 바뀌어야 할 위험이 있으므로 클래스에 구현이 미치는 영향을 격리한다.(인터페이스와 추상클래스 사용)
객체지향 언어를 다룰때 이러한 점들을 잘 알아두고 코드를 작성한다면 객체지향 장점을 잘 살릴수 있는 좋은 프로그램을 작성할수 있을것같다.
'3-2기 스터디 > 클린코드 독서' 카테고리의 다른 글
[6주차] 15~16장 정리 (0) | 2022.05.22 |
---|---|
[5주차] 14장 정리 (0) | 2022.05.17 |
[4주차] 클린코드 11~13장 정리 (0) | 2022.05.17 |
[2주차] 클린코드 4~6장 정리 (0) | 2022.04.06 |
[1주차] 클린코드 1~3장 정리 (0) | 2022.04.06 |
댓글