Move Method
- 정의
메소드가 자신이 정의된 클래스보다 다른 클래스의 기능을 더 많이 사용하고 있다면, 이 메소드를 가장 많이 사용하고 있는 클래스에 바슷한 몸체를 가진 새로운 메소드를 만들어라. 그리고 이전 메소드는 간단한 위임으로 바꾸거나 완전히 제거하라. - 동기
- 클래스가 너무 많은 동작을 가지고 있거나, 다른 클래스와 공동으로 일하는 부분이 너무 많아서 단단히 결합되어 있을 때 사용한다.
- 자신이 속해 있는 클래스보다 다른 클래스를 더 많이 참조하는 메소드가 존재하면 리팩토링 한다.
- 주의사항
- 어떤 부분이 지금 옮기려는 메소드에서만 사용된다면, 그 부분 또한 같이 옮기는 것이 낫다.
- 소스 클래스의 서브 클래스나 수퍼클래스에서 옮기려고 하는 메소드에 대한 다른 선언이 있다면, 다형성이 타겟 클래스에서도 역시 표현될 수 있는 경우에만 해당 메소드를 옮길 수 있을 것이다.
- 만약 소스 메소드를 참조하는 부분이 많다면, 소스 메소드를 위임 메소드로 남겨두는 것이 더 쉬운 방법이다.
- 소스 클래스의 일부부능 사용하려 할 때 다음 네 가지중 한 가지를 선택 할 수 있다.
- 사용 부분을 타겟 클래스로 옮긴다.
- 타겟 클래스에서 소스 클래스를 참조하는 부분을 새로 만들거나 사용한다.
- 메소드에 소스 객체를 파라미터로 넘긴다.
- 사용하려는 부분이 변수라면 파라미터로 넘긴다.
Move Field
- 정의 필드가 자신의 정의된 클래스보다 다른 클래스에 의해서 더 많이 사용되고 있다면, 타겟 클래스에 새로운 필드를 만들고 기존 필드를 사용하고 있는 모든 부분을 변경하라.
- 동기
- 어떤 필드가 자신이 속한 클래스보다 다른 클래스의 메소드에서 더 많이 사용되고 있는 것을 보면 그 필드를 옮겨라.
- Extract Class를 하고 있을 경우 필드를 먼저 옮기고 그 다음에 메소드를 옮겨야 한다.
- 주의사항
- 필드가 public으로 선언되어 있으면 Encapsulate Field를 사용한다.
- 필드가 private로 선언되어 있지 않다면, 필드를 참조하는 부분을 찾기 위해서 소스 클래스의 모든 서브 클래스를 살펴봐야 한다.
Extract Class
- 정의 두 개의 클래스가 해야 할 일을 하나의 클래스가 하고 있는 경우, 새로운 클래스를 만들어서 관련 있는 필드와 메소드를 예전 클래스에서 새로운 클래스로 옮겨라.
- 동기
- 클래스에 많은 메소드와 데이터를 가지고 있고, 너무 커서 쉽게 이해할 수도 없을 경우 데이터의 부분 집합과 메소드의 부분 집합이 같이 몰려다니는 것은 별도의 클래스로 분리할 수 있는 좋은 신호이다.
- 보통 같이 변하거나 특별히 서로에게 의존적인 데이터의 부분 집합 또한 별도의 클래스로 분리할 수 있다는 좋은 신호이다.
- 주의사항
- 클래스의 책임을 어떻게 나눌지를 결정하라.
- 양방향 링크가 필요할지도 모른다. 그러나 필요해지기 전에는 새로 만든 클래스에서 이전 클래스로 가는 링크를 만들지 마라.
- 양방향 링크를 가지고 있다면, 단방향 링크로 만들 수 있는지 알아본다.
Inline Class
- 정의 클래스가 하는 일이 많지 않은 경우에는, 그 클래스에 있는 모든 변수와 메소드를 다른 클래스로 옮기고 그 클래스를 제거하라.
- 동기
- 클래스가 더이상 제 몫을 하지 못하고 더 이상 존재할 필요가 없다면 Inline Class를 사용해라.
- 주의사항
- 소스 클래스 메소드에 대한 인터페이스를 분리하는 것이 이치에 맞다면, 인라인화 하기 전에 Extract Interface를 사용하라.
Hide Delegate
- 정의 클라이언트가 객체의 위임 클래스를 직접 호출하고 있는 경우, 서버에 메소드를 만들어서 대리객체(delegate)를 숨겨라.
- 동기 클라이언트가 서버 객체의 필드에 들어있는 객체에 정의된 메소드를 호출한다면, 서버 객체에 간단한 위임 메소드를 두어 위임을 숨김으로서 종속성을 제거 할 수 있다.
- 주의사항
Remove Middle Man
- 정의 클래스가 간단한 위임을 너무 많이 하고 있는 경우에는, 클라이언트가 대리객체를 직접 호출하도록 하라..
- 동기 서버 클래스에서 단지 간단한 위임 메소드가 많이 존재 하는 경우 리팩토링을 한다.
- 주의사항
Introduce Foreign Method
- 정의 사용하고 있는 서버 클래스에 부가적인 메소드가 필요하지만 클래스를 수정할 수 없는 경우에는, 첫 번째 인자로 서버 클래스의 인스턴스를 받는 메소드를 클라이언트에 만들어라.
- 동기 꼭 필요하지만 그 클래스가 제공하지 않는 서비스가 하나 있다. 소스 코드를 변경할 수 없다면 부족한 메소드를 클라이언트쪽에 만들어야 한다.
- 주의사항 만든 메소드는 클라이언트 클래스의 어떤 부분에도 접근 해서는 안 된다. 값이 필요하다면 값을 파라미터로 넘겨야 한다.
Introduce Local Extension
- 정의 사용하고 있는 서버 클래스에 여러 개의 메소드를 추가할 필요가 있지만 서버 클래스를 수정할 수 없는 경우, 필요한 추가 메소드를 포함하는 새로운 클래스를 만들어라. 이 확장 클래스를 원래 클래스의 서브클래스 또는 래퍼(wrapper) 클래스로 만들어라.
- 동기 꼭 필요하지만 그 클래스가 제공하지 않는 서비스가 많이 존재 하는 경우 리팩토링을 한다.
- 주의사항
- 서브 클래스 방식과 래퍼 방식 중 하는를 선택해야 할 때, 보통 서브클래스로 만든다.
- 객체가 가변성(mutable)라면 래퍼를 사용해라.
- 래퍼 클래스를 사용하는 경우 원래 클래스를 인자로 받을 때 오버라이드를 하지 말고 메소드를 추가해라.
'Programs > Refactoring' 카테고리의 다른 글
Refactoring - 데이터 구성 (1) | 2011.11.30 |
---|---|
Refactoring - 메소드 정리(Composing Methods) (4) | 2011.11.16 |
리팩토링(Refactoring) (4) | 2011.11.07 |