From 60a433d3454d0fa247ed322aa2fb1181c755e647 Mon Sep 17 00:00:00 2001 From: YHLEE9753 Date: Sun, 16 Jul 2023 00:00:54 +0900 Subject: [PATCH] docs: ch16 --- ...54\355\214\251\355\204\260\353\247\201.md" | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 "yonghoon/ch16_SerialDate \353\246\254\355\214\251\355\204\260\353\247\201.md" diff --git "a/yonghoon/ch16_SerialDate \353\246\254\355\214\251\355\204\260\353\247\201.md" "b/yonghoon/ch16_SerialDate \353\246\254\355\214\251\355\204\260\353\247\201.md" new file mode 100644 index 0000000..ca187c0 --- /dev/null +++ "b/yonghoon/ch16_SerialDate \353\246\254\355\214\251\355\204\260\353\247\201.md" @@ -0,0 +1,62 @@ +# 16. SerialDate 리팩터링 +- JCommon 라이브러리에 있는 org.jfree.date 패키지의 SeialDate 클래스를 리팩토링해보자 + +## 1. 첫째, 돌려보자 +### 문제점 +1. 실패 테스트 케이스는 없지만 모든 경우를 점검하지 않는다 + - 50프로 수준이며 이를 위해 독자적인 단위 테스트 케이스를 구현하였다. +2. 버그가 존제한다 + - 경계조건오류가 다수 존재(범위 체크 등) +3. 틀린 알고리즘이 존재한다 + - if 문이 항상 거짓인 경우도 있다. + +## 2. 둘째, 고쳐보자 +1. 수많은 import 문을 `java.text.*``java.util.*` 과 같이 `*`를 활용하여 코드량을 줄인다 +2. 한소스에 사용하는 언어를 줄인다(가급적이면 1개만) -> Java, English, Javadoc, HTML -> Java, English, HTML +3. 클래스의 명칭을 바꾼다 + - SerialDate 는 상품 번호같다 + - Date, Day 는 이미 너무 많이 쓰이고 있다 + - 그래서 DayDate 를 사용하겠다 +4. 단순한 상수모음은 Enum 을 활용한다 +5. serialVersionUID 변수는 직렬화를 제어하여 다른 버전의 직렬화한 데이터를 인식못한다 + - UID 값을 변경하지 않아 발생하는 오류는 난해하다 + - ㅊ라리 InvalidClassException 디버깅이 쉬우며 그래서 UID 변수를 없앤다. +6. 변수는 사용하는 클래스가 한정적이면 해당 클래스로 옮긴다 +7. 여러 클래스가 변수를 활용하며 이과정에서 추상클래스 사용자가 구현 정보를 알아야 하는 딜레마가 발생할 수 있다. + - ABSTRACT FACTORU 패턴을 통해 부모클래스가 자식클래스를 모르게 한다. + - 저자는 SINGLETON, DECORATOR, ABSTRACT FACTORY 패턴을 조합하였다. +8. 변수 이름만으로 의미가 확실하면 주석을 제거한다 +9. public 일 필요가 없으면 캡슐화한다. +10. 해당 변수가 특정 구현에 의존하지 않으면 변수가 사용되는 위치에 가깝게 둔다. + - Private 변수로 만들고 util 클래스를 만들어 정적메서드로 노출시키는 것도 고려해보자 +11. 단어 이름을 짓는거를 고민하자(수학적 명칭도 고려가능) +12. 사용하지 않는 변수와 메서드는 제거한다 +13. 컴파일러가 자동으로 기본 생성자를 만든다면 해당 코드도 제거한다 +14. final 을 없앤다(final 을 사용하라는 사람도 있어 의견이 분분) +15. if 문은 로직을 통해 줄인다(예) || ) +16. 호출 메서드가 1개뿐이라면 2개 메서드를 1개로 줄인다(책임에 대해서는 항상 고민하자) +17. 리팩터링하면서 책임이 너무 커지면 분할하자 +18. 서술적인 표현으로 가독성을 올리자 +19. static 변수를 인스턴스 변수로 변경하자 +20. 메서드의 로직이 복잡한 경우 로컬 변수(임시 변수 설명)를 사용해 이해하기 쉽게 하자 + - 임시 변수는 단일 작업에만 필요한 값을 저장하는 데 매우 유용하며 한 번만 사용할 수있는 변수를 사용하여 개체가 복잡해지지 않도록합니다. + - 또한 복잡한 작업을 분류하거나 작업 범위를 변경할 때 다른 인스턴스에서 값을 설정하는 데 매우 유용합니다. + - 일시적이 될 때 변수를 선언하기 때문입니다 +21. 리팩터링 하다보면 간혹 테스트 케이스에서만 사용하는 메서드 변수가 존재한다. 속지말고 전부 제거하자 +22. 특정 클래스에 물리적으로 의존성은 없지만 논리적으로 의존성이 존재하는 경우가 있다. + - 데이터를 가져다 사용하지는 않지만 논리적으로 유사한 경우이다 + - 의견이 분분하지만 저자는 논리적으로 의존하면 물리적으로도 의존해야한다고 보고 있다 + - 그래서 추상클래스에서 추상메서드로 구현하고 다른 클래스에서 해당 데이터를 가져오는 메서드도 같이 만들어서 의존성을 명확하게 하였다 +23. if 문 연쇄가 복잡해 보이는 경우 enum 에서 if 를 사용하였다(전략패턴 적용) + +### 최종 정리 +- 주석을 간단하게 +- enum 을 모두 독자적인 소스 파일로 변경 +- 정적 변수, 정적 메서드는 DateUtil 이라는 새 클래스로 옮긴다 +- 일부 추상화 수준을 변경 +- 중복을 제거 +- 네이밍 고민 +- 알고리즘 수정 + +## 결론 +명확한 리팩토링 기준만 있다면 리팩터링이 한결 쉬워진다. \ No newline at end of file