Skip to content

Latest commit

 

History

History
62 lines (58 loc) · 4.36 KB

ch16_SerialDate 리팩터링.md

File metadata and controls

62 lines (58 loc) · 4.36 KB

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 이라는 새 클래스로 옮긴다
  • 일부 추상화 수준을 변경
  • 중복을 제거
  • 네이밍 고민
  • 알고리즘 수정

결론

명확한 리팩토링 기준만 있다면 리팩터링이 한결 쉬워진다.