16장 SerialDate 리팩토링

첫째, 돌려보자

확인한 내용

  • 테스트 케이스는 실패하지 않고 있지만, 코드의 전체 범위를 점검하지 않고 있음
  • 아마도 실패하는 테스트 케이스는 주석으로 처리한 듯
  • stringToWeekdayCode()는 대소문자를 구분해 통과하게 되어있다.
  • getFollowingDayOfWeek() 메서드의 버그: 다음 토요일을 가져올 때, 연도가 바뀌면 정확하게 가져오지 못함 = 경계 조건 오류

둘째, 고쳐보자

  • 코드를 고칠 때마다 JCommon 단위 테스트와 새로 작성한 테스트를 실행

문제점

  • 클래스 이름이 SerialDate인 이유는 일련번호를 사용해 클래스를 구현
    • 일련번호라는 용어가 정확하지 못함, 상대 오프셋(relative offset)이나 서수(Ordinal)가 더 적절하다
  • 클래스의 이름을 들었을 때에는 구현 클래스같이 느껴지지만, 실제로는 추상 클래스이기 때문에 추상적인 이름 Date가 적절하지만 이는 java와 겹칠 수 있어 DayDate라고 변경
    • MonthConstants는 상수 모음이기 때문에 enum으로 정의
      • isValidMonthCode 메서드 삭제: enum으로 받기 때문에
      • monthCodeToQuarter 메서드 삭제: enum으로 받기 때문에
  • serialVersionUID: 직렬화를 제어하는 변수로, 값을 변경시 이전 소프트웨어에서 직렬화한 DayDate를 인식하지 못한다.
    • 변수를 선언하지 않으면, 컴파일러가 자동으로 생성하는데 이 방법이 더 안전하다고 느껴짐 -> 만약 누군가 변경하지 않아서 생긴 버그를 찾는 것보다 이게 더 나을 것이라는 의견
  • EARLIEDST_DATE_ ORDINAL의 값이 0이 아닌 2인 이유는 마이크로소프트 엑셀에서 날짜를 표현하는 방식과 관련이 있음 -> 하지만 이 내용은 excel과 관련이 없어보임
    • DayDate에 속하지 않으며,SpreadsheetDate 클래스로 옮겨져야 한다고 생각
  • 기반 클래스는 파생 클래스를 몰라야 바람직함, 그래서 ABSTRACT FACTORY 패턴을 적용해 DayDateFactory를 생성

  • final 제거
    • 로버트 시몬스: 코드 전체에 final을 사용하라고 강력 권장
    • 저자: 상수 몇군데를 제하면 별다른 가치가 없고, 코드만 복잡하게 만듬, 테스트 커버로 final 부분을 다 커버함
  • 첫번째 getMonths는 두번째 getMonths를 호출 -> 하나로 합쳐 단순화

  • monthCodeToQuarter(): 기능 욕심으로 보임

  • 출력 형식을 선택하는 플래그는 가급적 피하는 것이 좋음

  • add와 plus: addDays가 date 객체를 변경한다고 생각하게 함, plus가 더 적절한 이름

  • 논리적 의존성: 서수 날짜 시작일의 요일에 암시적으로 의존, 0번째 날짜의 요일에 의존
    • 논리적 의존을 물리적 의존으로 드러내자

결론