• 객체에서 가장 중요한 것은 인터페이스.
  • 이해와 사용이 쉬운 인터페이스를 작성하는 기술이야 말로 좋은 객체지향 소프트웨어 개발에 꼭 필요.
  • 인터페이스를 더 쉽게 만드는 리펙토링 기법을 설명 함.

1. 메서드명 변경 Rename Method

1.1 동기

  • 저자가 주장하는 코드 스타일의 가장 중요한 부분은 복잡한 과정을 여러 작은 메서드로 잘개 쪼개는것.
  • 메서드를 쪼개는 과정을 잘못 적용할 경우 메서드의 역할을 파악하기 힘들어짐.
  • 이런 문제를 방지하기 위해 메서드명을 잘 지어야함.

1.2 방법

  • 메서드가 상위클래스나 하위클래스에 구현 되어 있는지 검사.
  • 원본 메서드는 그대로 두고, 변경될 새 이름으로 새 메서드를 선언.
  • 원본 메서드의 내용을, 새 메서드로 복사 후 적절히 수정.
  • 새 메서드를 호출하게 원본 메서드의 내용을 수정
  • 원본 메서드를 참조 하는 부분을 새 메서드를 참조 하도록 수정
  • 원본 메서드 삭제
  • 각 단계를 수행시 컴파일 및 테스트

2. 매개변수 추가 Add Parameter

2.1 동기

  • 메서드 수정시 전달하지 않은 정보가 필요할 때 매개변수를 추가해야 함.

2.2 방법

  • 메서드가 상위클래스나 하위클래스에 구현 되어 있는지 검사.
  • 원본 메서드는 그대로 두고, 추가 매개변수를 구현한 동일한 메서드를 선언 (오버로딩).
  • 원본 메서드의 내용을, 새 메서드로 복사 후 적절히 수정.
  • 새 메서드를 호출하게 원본 메서드의 내용을 수정
  • 원본 메서드를 참조 하는 부분을 새 메서드를 참조 하도록 수정
  • 원본 메서드 삭제
  • 각 단계를 수행시 컴파일 및 테스트

3. 매개변수 제거 Remove Parameter

3.1 동기

  • 혹시 나중에 다시 필요할 수도 있다는 핑계로 자기 합리화에 빠져 매개변수 제거를 꺼리지 말자.
  • 필요없는 매개변수를 제거하지 않음으로 인해서, 해당 매서드를 사용하는 모든곳이 불필요한 추가작업이 필요해 진다.

3.2 방법

  • 메서드가 상위클래스나 하위클래스에 구현 되어 있는지 검사.
  • 하위클래스나 상위 클래스에서 제거하려는 매개변수를 사용하고 있다면 이 리팩토링은 하지 말아야 한다.
  • 원본 메서드는 그대로 두고, 제거할 매개변수를 제거한 동일한 메서드를 선언 (오버로딩).
  • 원본 메서드의 내용을, 새 메서드로 복사 후 적절히 수정.
  • 새 메서드를 호출하게 원본 메서드의 내용을 수정
  • 원본 메서드를 참조 하는 부분을 새 메서드를 참조 하도록 수정
  • 원본 메서드 삭제
  • 각 단계를 수행시 컴파일 및 테스트

4. 상태 변경 메서드와 값 반환 메서드를 분리 Separate Query from Modifier

4.1 동기

  • 값 반환 기능과 객체 상태 변경 기능이 한 메서드에 들어 있을 땐 질의 메서드와 변경 메서드로 분리.

4.2 방법

  • 원본 메서드와 같은 값을 반환하는 메서드를 작성
  • 원본 메서드의 return값을 새로 작성한 값 반환 메서드로 수정
  • 원본 메서드의 호출을 값 반환 메서드 호출로 수정
  • 값 반환 메서드 호출 행 앞에 원본 메서드 호출을 추가
  • 원본 메서드를 void타입으로 수정 및 return문 제거
  • 각 단계를 수행시 컴파일 및 테스트

5. 메서드를 매개변수로 전환 Parameterize Method

5.1 동기

  • 기능은 비슷하지만 몇가지 값에 따라 결과가 달라지는 메서드가 여러 개 있을 때 각 메서드를 전달된 매개변수에 따라 다른 작업을 처리하는 하나의 메서드로 만든다.

5.2 방법

  • 여러 메서드를 대체할 수 있는 매개변수 메서드를 작성
  • 새 메서드를 호출하도록 원본 메서드 하나를 수정
  • 모든 메서드를 대상으로 반복
  • 각 단계를 수행시 컴파일 및 테스트

6. 매개변수를 메서드로 전환 Replace Parameter with Explicit Methods

6.1 동기

  • 매개변수로 전달된 값에 따라 메서드가 다른 코드를 실행할 땐 그 매개변수로 전달될 수 있는 모든 값에 대응하는 메서드를 각각 작성
  • 매개변수 값이 많이 변할 가능성이 있을 때는 실시하면 안된다.
  • 조건에 따라 다른동작을 실행하게 해야 할 때는 조건문을 재정의로 전환 실시

6.2 방법

  • 매개변수의 각 값에 해당하는 개별 메서드를 작성
  • 조건문의 각 절마다 해당되는 새 메서드 호출
  • 조건문이 든 원본 메서드의 각 호출 부분을 알맞은 새 메서드 호출로 변경
  • 조건문이 든 매개 변수 메서드 삭제
  • 각 단계를 수행시 컴파일 및 테스트

7. 객체를 통째로 전달 Preserve Whole Object

7.1 동기

  • 객체가 한 객체에든 여러값을 메서드 호출 때 매개변수로 전달하고 있다면, 이 기법을 적용
  • 객체를 통으로 전달하면 호출객체와 전달된 객체가 의존하게 되는데, 이로인해 의존성 구조가 망가질것 같으면 적용하지 말아야 한다.
  • 호출 객체에서 사용하는 값이 하나뿐 이라면, 그값 하나만 전달 하는 것이 효율적이다.
  • 다른객체에 있는 많은 값들을 사용 한다면, 메서드 이동도 고려해 보자.
  • 자신의 객체 자체의 데이터값을 여러개 사용한다면 this를 이용하자.

7.2 방법

  • 데이터가 속한 통 객체에 새매개변수를 작성
  • 통 객체에서 가져와야 할 매개변수를 파악
  • 한 매개 변수를 선택하여, 메서드안에 그 매개변수를 참조하는 부분을 넘겨받은 통 객체 안의 적절한 메서드 호출로 변경.
  • 그 매개변수를 삭제
  • 모든 매개변수를 대상으로 위내용 반복
  • 삭제한 매개변수를 가져오는 호출 메서드 안의 코드 삭제
  • 각 단계를 수행시 컴파일 및 테스트

8. 매개변수 세트를 메서드로 전환 Replace Parameter with Method

8.1 동기

  • 객체가 A 메서드를 호출해서 그 결과를 B 메서드에 매개변수로 전달하는데, 결과를 매개변수로 받는 B 메서드도 직접 A 메서드를 호출할수 있을땐 매개변수를 없애고 B메서드가 A 메서드를 호출하게 변경.

8.2 방법

  • 매개변수를 사용한 계산 부분을 별도의 메서드로 뺀다
  • 메서드 안의 매개변수 사용 부분을 추출한 메서드 호출로 수정
  • 매개변수를 대상으로 매개변수 제거를 실시
  • 각 단계를 수행시 컴파일 및 테스트

9. 매개변수 세트를 객체로 전환 Introduce Parameter Object

9.1 동기

  • 여려개의 매개변수가 항상 붙어 다닐 땐 그 매개변수들을 객체로 바꾼다

9.2 방법

  • 대체할 매개변수 그룹에 해당하는 새클래스를 작성하고, 그 클래스를 변경 불가로 만든다
  • 새 데이터 뭉치에 매개변수 추가를 적용, 새매개변수에 기본 값을 사용
  • 데이터 뭉치 안의 각 매개변수마다 시그너처에서 해당 매개변수를 삭제, 그 값 대신 매개변수 객체를 사용하도록 수정
  • 매개변수 삭제를 전부 완료 했으면, 메서드 이동을 적용하여 매개변수 객체로 옮길수 있는 기능을 찾는다.
  • 각 단계를 수행시 컴파일 및 테스트

10. 쓰기 메서드 제거 Remove Setting Method

10.1 동기

  • 생성할 때 지정한 필드 값이 절대로 변경되지 말아야 할 땐 그 필드를 설정하는 모든 쓰기 메서드를 삭제
  • 이기법은 프로그래머가 간접적인 변수 접근을 맹목적으로 이용할 때 실시해야 함다

10.2 방법

  • 쓰기 메서드가 생성할 때나 생성자가 호출하는 메서드에서만 호출되는지 검사
  • 쓰기 메서드가 생성자 안이나 생성자가 호출한 메서드 안에서만 호출되는지 검사
  • 변수에 직접 접근할 수 있게 생성자를 수정
  • 쓰기 메서드를 삭제
  • 각 단계를 수행시 컴파일 및 테스트

11. 메서드 은폐 Hide Method

11.1 동기

  • 메서드가 다른 클래스에 사용되지 않을 땐 접근 권한을 private로 만든다

11.2 방법

  • 메서드의 개방도를 낮출 여지가 있는지 정기적으로 검사
  • 각 메서드를 가능하면 private로 선언
  • 각 단계를 수행시 컴파일 및 테스트

12. 생성자를 팩토리 메서드로 전환 Replace Constructor with Factory Method

12.1 동기

  • 객체를 생성할 때 단순한 생성만 수행하게 해야 할 땐 생성자를 팩토리 메서드로 교체
  • 이 기법을 적용할 가장 확실한 상황은 분류 부호를 하위 클래스로 바꿀때 적용

12.2 방법

  • 팩토리 메서드를 작성, 메서드 내용을 기존 생성자 호출로 수정
  • 모든 생성자 호출을 팩토리 메서드 호출로 변경
  • 생성자를 private로 변경
  • 각 단계를 수행시 컴파일 및 테스트

13. 하향 타입 변환을 캡슐화 Encapsulate Downcast

13.1 동기

  • 메서드가 반환하는 객체를 호출 부분에서 하향 타입 변환해야 할 땐 하향 타입 변환 기능을 메서드 안으로 옮긴다
  • 클라이언트가 하향 타입 변환을 하게 하지 말고, 가능하면 항상 가장 구체적인 타입을 작성

13.2 방법

  • 메서드 호출의 결과로 반환된 값을 하향 타입 변환해야 하는 각종 상황을 찾는다
  • 하향 타입 변환 코드를 메서드 안으로 옮긴다
  • 각 단계를 수행시 컴파일 및 테스트

14. 에러 부호를 예외 통지로 교체 Replace Error Code with Exception

14.1 동기

  • 메서드가 에러를 나타내는 특수한 부호를 반환할 땐 그 부호 반환 코드를 예외 통지 코드로 바꾼다

14.2 방법

  • 확인된 예외와 미 확인 예외중 어느 것을 사용해야 할지 판단
  • 그 예외를 사용하는 새 메서드를 작성
  • 원본 메서드 내용을 수정해서 새 메서드 호출로 변경
  • 원본 메서드 호출을 전부 새 메서드 호출로 변경
  • 원본 메서드 삭제
  • 각 단계를 수행시 컴파일 및 테스트

15. 예외 처리를 테스트로 교체 Replace Exception with Test

15.1 동기

  • 호출 부분에 사전 검사 코드를 넣으면 될 상황인데 예외 통지를 사용했을 땐 호출 부분이 사전 검사를 실시하게 수정
  • 예외 처리는 예기치 못한 에러에 사용해야 한다.
  • 예외 처리를 조건문 대용으로 사용해선 안 된다.

15.2 방법

  • 테스트를 앞에 넣고 catch 절의 코드를 if 문의 적절한 절로 복사
  • catch 절이 실행 되는지 여부가 표시되게 catch 절에 어설션을 넣는다
  • catch 절을 삭제, 다른 catch 절이 없으면 try도 삭제
  • 각 단계를 수행시 컴파일 및 테스트