Chapter 14
점진적인 개선: 명령행 인수 구문분석기 코드 개선
- 깨끗한 코드를 짜려면 먼저 지저분한 코드를 짠 뒤에 정리해야한다.
- 인수 유형은 다양하지만 모두가 유사한 메서드를 제공할 경우 클래스 하나가 적합
- TDD: 언제 어느 때라도 시스템이 돌아가야 한다.
- 각 인수 유형을 처리하는 코드를 모두 한 클래스에 넣고 나서, 이후 파생 클래스들을 만들어 코드를 분리한다.
- 프로그램 구조를 조금씩 변경하는 동안에도 시스템의 정상 동작을 유지하기 쉽기 때문: 이후 파생 클래스를 만들어 기능을 분산
- protected 변수인 상위클래스 변수를 하위 클래스로 내려 private 변수로 선언하기도 함
- 한 함수에서 if문으로 유형을 일일이 확인하는 대신 파생 클래스로 내려서 if문을 제거한다.
Chapter 15
JUnit 들여다보기: JUnit 라이브러리 리팩토링
- 한 함수에서 몇 줄은 변수를 반환하고, 몇 줄은 반환값이 없는 형태로 사용방식이 일관적이지 못할 경우 반환값을 임의로 줌으로써 코드 가독성을 높이기도 한다.
- findCommonSuffix가 findCommonPrefix의 특정 연산에 의존할 경우: 함수간의 시간결합이 있는 상황이 있을 수 있다.
- 뒤에서 부르는 함수에서 첫 함수의 반환값을 이용하게끔 구성함으로써 호출 순서를 보장할 수 있다.
- 하지만 꼭 인수에 prefixIndex를 넣어야했던 이유를.. 의미론적으로 설명하기 어려움
- 따라서 모듈화를 없애고 한 메소드로 결합하는 형태로 시간결합을 해결
- 항상 모듈화가 좋은 것은 아니고, 추후에 코드를 읽는 사람이 개별적으로 특정 메소드만 호출했을 때 문제가 생기지 않도록까지 고려를 한 다음, 다시 메소드를 합치는 경우도 있다.
Chapter 16
SerialDate 리팩터링: SerialDate 라이브러리 리팩토링
- 코드 커버리지 분석도구: 클로버!
- static final 상수 모음에 불과한 클래스들 -> 옛날 자바 프로그래머들이 많이 쓰던 기교 -> enum으로 정의하자!
- 부모 클래스는 파생 클래스를 몰라야 바람직: abstract factory 패턴을 적용하자!
- 약간 부모 클래스와 파생 클래스 사이의 어떤 완충제같은 느낌.. 파생 클래스만 넣기는 모두에게 필요할 것 같은데 부모 클래스에 넣기는 구현적인 내용을 많이 포함하고 있을 때..
- 추상 메서드로 위임하는 정적 메서드 (abstract class에 들어가는 static method들): singleton, decorator, abstract factory 패턴 조합을 이용
- 부모 클래스와 자식 클래스를 나누는 상황에서 변수가 특정 클래스에서만 사용되더라도 특정 구현에 의존하지 않는 이상 하위 클래스로 위치를 변경하지 않는다.
- 단지 변수가 사용되는 위치에 가깝게 위치만 변경할 뿐
- 한 메서드가 다른 메서드를 호출하며 출력 형식을 선택하는 플래그를 넘김 (축약 여부에 대해서 true/false로 넘기면 그에 따라 출력에 축약을 할건지/말건지를 담아서 return)
- 모듈화를 없애서 이러한 형태를 제거하는 것이 바람직
addDays
vs. plusDays
- 전자는
sample.addDays(5)
를 하면 sample의 값이 변경되는지, 아니면 단순히 sample 값에 5를 더한 값을 return 하는지 판단이 모호
- 후자와 같이
sample.plusDays(5)
를 하면 sample의 값이 변경된다기보다 sample 값에 5를 더한 값을 return 한다고 좀더 쉽게 예측이 가능
- 클래스로 만들어지는 인스턴스를 인수로 받아 클래스 메서드를 호출하는 인스턴스 메소드
- 진짜 인스턴스 메소드로 변경하고 인수로 들어가는 인스턴스 제거
- 모든 enum 클래스는 toString을 사용하면 이름이 반환된다.
- ex) weekInMonth.toString (weekInMonth: enum 객체)
- enum 내부에 abstract method를 선언해두고, 각 enum 값에 대해 명시할 때 해당 메소드를 구현함으로써 구성할 수 있다.