리팩터링
1. 리펙터링이란
겉으로 보이는 동작의 변화없이 소프트웨어의 내부 구조(설계)를 바꾸는 작업
2. Rename (Alt + Shift + R) => 이름변경
패키지, 클래스 메서드, 필드, 변수 파라미터의 이름을 한번에 바꾸는데 사용하며, 코드의 내용과 관계가 없는 프로젝트 이름이나 소스폴더의 이름도 이 기능으로 바꿀 수 있다.
- Update reference : 이름을 바꾸려는 요소를 참조하는 모든곳에도 이름을 바꾼다. 디폴트
- Keep original method as delegate to renamed method : 해당 메서드의 이름을 변경하는 것이 아니라 새로 지정한 이름으로 메서드를 추가하고 원래 메서드는 새로 지정한 이름의 메서드를 호출하도록한다.
- Rename getter/Rename setter : 필드를 선택했을 때만 나타나며, 해당 필드에 대한 get/set 메서드 이름 역시 바꿀지 지정하는 옵션
- Update texual occurrences in comments and strings : 주석이나 문자열에 있다면 이것 역시 바꿀지를 선택하는 옵션
- Update fully qualified name in non-Java file : java 파일이 아닌 다른 파일에 나타나면 이를 바꾸도록 한다.
- Rename subpackages : 패키지 이름을 바꿀때 나타나며, 해당 패키지의 서브 패키지 이름도 변경할 지를 지정한다.
3. Move (Alt + Shift + V) => 이동
클래스를 다른 패키지로 이동, 메서드/필드를 다른 클래스로 이동, 패키지를 다른 프로젝트로, 프로젝트를 다른 위로 이동이 가능하다.
4. Change Method Signature (Alt + Shift + C) => 메서드 설정 변경
메서드의 시그니처가 마음에 들지 않는 경우에 사용.
- 접근지정자 변경 : public, private 등
- 리턴 타입 변경 : 사용자가 입력
- 메서드 이름 변경 : 사용자가 입력
- 파라미터 타입/이름/순서/추가/삭제
- 예외 추가 삭제 : eXCEPTIONS 탭에서 메서드가 throws 수 있는 예외를 변경할 수 있다.
5. Extract Method (Alt + Shift + M) => 메서드 내용 변경
메서드가 너무 길때, 일부 기능을 뽑아서 새로운 메서드나, 다른 메소드로 이동시 사용
6. Extract Local Variable (Alt + Shift + L) => 변수화 처리
수식이 복잡한 경우 수식 일부의 의미나 목적을 임시 변수를 사용하면 코드를 이해하기가 쉬워진다.
예를 들면
String osname = System.getProperty("os.name");
if(osname.indexOf("windows") >= 0){
}
이런 코드를
String osname = System.getProperty("os.name");
boolean isWindows = osname.indexOf("windows") >= 0;
if(isWindows){
}
이런식으로 변경하는 작업을 할때 사용한다.
7. Extract Constant => 상수화 처리
하드코딩되어 있는 값을 상수화 하여, 차후에 의미와 목적이 명확해질 뿐 아니라 나중에 상수 값을 바꿔야 하는 경우 실수할 확일을 줄일 수 있다.
예를 들면, return 9.8 * m * b; 이런 코드가 있다고 하면, 9.8 부분을 블록하여 Extract Constant를 클릭 시, 다이얼로그가 뜨고, 거기에 상수명을 입력하면 자동으로
상수가 정의돠고, 숫자 리터럴을 쓰던 부분이 상수로 대체된다.
8. InLine (Alt + Shift + I) => 메소드를 지우고, 호출한 곳에 코드가 이동
어떤 메서드는 너무 단순하고 내용도 명확하여 굳이 메소드로 되어 있을 필요가 없는 경우가 있다.
이런경우 InLine을 사용하여 해당 메소드를 지우고 호출한 곳에 코드가 이동하게 사용할때 사용된다.
사용방법은 getPIValue()라고 있을때 그 부분을 선택하고, InLine을 선택하면 자동진행된다.
9. Convert Anonymous Class to Nested => 익명 클래스네임을 변경
익명(anonymous) 클래스는 편리하게 사용할 수 있지만, 클래스에서 복잡한 작업을 처리한다거나, 클래스의 인스턴스를 다른 곳에서도 사용할 필요가 있는 경우에는 이 클래스에 이름을 부여해 사용하는 편이 좋을 것이다.
new ActionListener() {} 이런 코드가 있다면 ActionListener를 선택하고, 해당 메뉴를 선택 시 다이얼로그가 출력되고, Rename을 할 수 있다.
10. Convert Member Type to Top Level => 내부 클래스를 별도의 독립된 클래스로 변경
11. Convert Local Variable to Field => 지역변수를 필드로 변경할때
12. Extract Superclass => 수퍼클래스로 뽑아내기
두 개 이상의 클래스가 공통된 부분을 가지고 있다면 공통된 부분을 수퍼클래스로 뽑아낼 수 있다.
사용자가 공통된다고 생각하는 부분을 체크하여 진행해야 되는 불편함은 있다.
13. Extract Interface => 인터페이스로 뽑아내기
어떤 클래스 인터페이스의 동일한 부분 집합을 여러 클라이언트에서 사용하고 있거나, 두 개 이상의 클래스가 공통된 인터페이스를 가지는 부분이 있다면, 그 부분 집합을 인터페이스로 뽑아낼 수 있다.
14. Use Supertype Where Possible => 수퍼타입을 자동으로 변경
서브타입이 사용하는 곳 중에서 수퍼타입을 사용하게 하는 것이 가능할 경우 수퍼타입을 사용하도록 바꾼다.
15. Push Down => 메서드 하위로 이동
수퍼클래스에 정의된 메서드나 필드가 서브클래스의 일부에서만 사용된다면 그 메서드나 필드는 실제 사용되는 서브클래스로 옮기는 것이 좋다.
이럴때 사용할 수 있는 것이 Push Down 리팩터링이다.
16. Pull Up => 메서드 상위로 이동
같은 수퍼클래스를 가지는 서브클래스에서 동일한 필드를 가지고 있거나 또는 동일한 작업을 하는 메서드가 정의되어 있다면 이는 중복이다. 따라서 이런 필드나 메서드는 수퍼클래스로 옮기는 것이 좋다. 이럴때 사용할 수 있는 것이 Pull Up 이다.
17. Extract Class => 클래스 필드 분리
클래스에 지나치게 많은 필드를 가지고 있다면 이는 해당 클래스가 너무 많은 일을 한다는 것을 나타내는 징조이다. 이런 경우 일부 책임을 분리해 다른 클래스를 만들 수 있는 경우가 있다. 이럴때 Extract Class를 사용한다.
18. Introduce Parameter Object => 파라미터 클래스화 하기
여러 메서드에서 공통적으로 쓰이는 파라미터 목록이 있다면 이는 별도의 클래스로 뽑아낸 다음 이 클래스의 인스턴스를 메서드의 파라미터로 넘기는 것이 좋다.
이럴때 Introduce Parameter Object 리팩터링을 사용 할 수 있다.
리팩터링 후 확인 해보면, 파라미터를 담을 새로운 클래스가 생성되고, 원래의 메서드는 새로 생성된 클래스의 인스턴스를 파라미터로 넘기도록 바뀐다.
19. Introduce Indirection
선택한 메서드로 작업을 위임하는 정적 인디렉션 메서드를 만드는 리팩터링이다.
20. Introduce Factory => 생성자를 팩터리 메서드로 변경
클래스의 생성자를 private 또는 protected로 만들고 static 팩토리 메서드를 추가하고, 생성자를 호출하는 부분을 모두 팩터리 메서드를 호출하도록 바꾼다.
21. Introduce Parameter
메서드 내에서 사용하는 특정 값이나 어떤 값을 리턴하는 수식을 메서드의 파라미터로 받도록 바꾸고 싶을 때 사용한다.
22. Encapsulate Field => 캡슐화 하기
객체지향 프로그래밍을 할 때 클래스에 public 필드가 있는 것은 바람직하지 못하다. 필드가 public으로 선언되어 있는 경우에는 캡슐화의 원칙에 위배된다.
따라서, public 필드가 있는 경우에는 이를 private로 바꾸고, get/set 메서드를 통해 접근하도록 바꾸어야 한다.
모든 필드에 대한 get/set 메서드를 정의한다해서, 클래스가 캡슐화 되는 것은 아니다.
23. Generalize Declared Type =>수퍼타입을 자동으로 변경
변수의 타입을 안전하게 수퍼타입으로 변경할 수 있는 경우 수퍼타입으로 바꿔주는 리펙토링이다.
앞에 설명한 "14. Use Supertype Where Possible" 리펙터링과 유사하나, 이 리팩터링은 자신이 선택한 변수에 대해서만 적용된다는 점이 다르다.
24. Infer Generic Type Arguments
J2SE 5.0부터는 가독성과 정적 타입 안정성 개선을 위해 제너릭(Generic)을 사용할 수 있다.
원시타입(raw type)을 사용하는 부분에 제너릭을 사용할 수 있게 하는 리팩터링으로 프로젝트나 패키지 또는 타입에 적용할 수 있다.
제너릭을 사용하지 않으면 타입 캐스트를 곳곳에 사용해야 함으로, 코드의 가독성이 떨어질 뿐 아니라, 실행 시 예외가 발생할 가능성도 있음으로 안정성도 떨어짐.
25. Migrate JAR File =>기존에 사용하던 Jar를 다른 Jar로 일괄 변경
프로젝트에서 만든 결과물은 Jar 파일로 만들어서 다른 프로젝트에서 사용하기 쉽게 할 수 있다. 그런데 다른 프로젝트에서 생성한 Jar 파일을 사용하는 프로젝트의 경우 Jar 파일의 버전이 바뀔 때 이를 적용하는 작업이 쉽지 않을 수 있다. 이럴때 사용하는 리펙터링 이다.
26. Create Script/Apply Script =>실행된 리팩터링 스크립트 생성
Create Script를 이용하면 지금까지 워크스페이스에서 실행된 리팩터링에 대한 스크립트를 생성 할 수 있다.
27. History => 실행된 리팩터링의 히스토리를 볼 수 있는 기능