* 메서드 추출 리팩토링
- 한 메서드안에 이런저런 세세한 처리가 많다면 그런 처리를 묶어서 나누고 독립된 메서드로 추출하고
추출한 메서드에는 적절한 이름을 붙임.
- 장황한 코드가 읽기 편해짐.
- 장단점 : 각 메서드가 짧아지는 장점이 있는 반면 메서드 개수가 늘어남
아래는 리팩토링 하기전의 예제 프로그램입니다.
* Banner.java
package Banner;
public class Banner {
private final String _content;
public Banner(String content) {
_content = content;
}
public void print(int times) {
// 테두리 출력
System.out.print("+");
for (int i=0; i<_content.length(); i++) {
System.out.print("-");
}
System.out.println("+");
// 내용출력
for(int i=0; i< times; i++) {
System.out.println("|" + _content + "|");
}
// 테두리 출력
System.out.print("+");
for(int i=0; i<_content.length(); i++) {
System.out.print("-");
}
System.out.print("+");
}
}
* Main.java
package Banner;
public class Main {
public static void main(String[] args) {
Banner hello = new Banner("Hello, World!");
hello.print(3);
}
}
* 리팩토링 순서
1) 새로운 메서드에 적절한 이름 붙이기
- 메서드를 추출하기 위해 적절한 이름을 명명함. 메서드 이름은 '동사 + 명사' 순으로 짓는것이 보통임.
- 메서드의 이름은 '무엇을 하는가'를 알 수 있게 짓는 것이 중요함.
- 메서드의 이름을 짓는것은 매우 중요함.
- 참고로 메서드명 변경도 리팩토링 중 하나임. 이는 알맞지 않는 메서드명을 알맞게 바꾸는 리팩토링임.
2) 기존 메서드에서 새로운 메서드로 코드 복사
- 새로 만드는 메서드는 private으로 지정하는게 좋음
3) 메서드 내부의 지역변수 검토
- 복사한 코드에 변수가 있다면 변수 역할을 잘 생각해서 다뤄야 함.
- 복사한 코드 내부에 닫힌 변수는 '메서드 지역 변수'가 됨. 변수 선언이 없다면 새로 선언해야 함.
4) 메서드 매개변수 검토
- 복사한 코드에 변수가 있고 해당 변수가 입력 역할을 하고 있다면 '메서드 매개변수'로 바꿔야 함.
5) 메서드 반환값 검토
- 복사한 코드에 값을 수정하는 변수가 있다면 메서드의 '출력'인 메서드 반환값이 될 수 있을지 검토해야 함.
6) 컴파일
- 컴파일해서 문법 에러가 없는지 확인
- 리팩토링에서 문법 확인용으로 사용할 때가 많음.
그럼 리팩토링 후 달라진 코드를 작성해 보겠습니다.
* 리팩토링 후 Banner.java
package Banner;
public class Banner {
private final String _content;
public Banner(String content) {
_content = content;
}
public void print(int times) {
printBorder();
printContent(times);
printBorder();
}
private void printBorder() {
System.out.print("+");
for (int i=0; i<_content.length(); i++) {
System.out.print("-");
}
System.out.println("+");
}
private void printContent(int times) {
for(int i=0; i< times; i++) {
System.out.println("|" + _content + "|");
}
}
}
리팩토링은 외부에서 보는 프로그램 동작은 바꾸지 않고 프로그램의 내부 구조를 개선.
메서드 추출을 해도 외부에서 보는 프로그램 동작은 변하지 않음.
* 역리팩토링
- 메서드 추출은 역 리팩토링이 있음.
- 이를 일컬어 메서드 인라인화라고 함.
- 메서드 인라인화는 너무 짧은 메서드가 리팩토링 대상, 메서드로 만들 정도가 아닌 간단한 처리라면 메서드 본문을 메서드 호출 부분에 직접 작성함.
이렇게 하면 메서드 개수가 줄어듬.
- 오버라이드된 메서드는 인라인화 하면 안됨.
* 메서드 추출은 당연한건가?
- 경험이 풍부한 프로그래머는 메서드 추출은 당연하다고 생각함.
- 메서드 추출을 가볍게 생각하면 안됨.
- 프로그램을 대충 수정하는 것이 아니라 '지금 난 메서드 추출을 하고 있다'고 의식하는 게 중요함.
* 메서드가 길어지는 경우
- 길어서 읽기 어려운 메서드를 처음부터 만들려고 하는 프로그래머는 없음.
- 하지만 프로그램은 만든 후에도 여러 번 수정하기 마련임.
- 프로그램에 다음과 같은 수정을 몇 번이고 반복하다 보면 어느새 메서드가 길어져 버리는게 현실임.
(에러 처리 추가, 버그 수정, 신기능 추가)
- 길어진 메서드를 방치하면 더욱 길어지는 경향이 있음, 그러므로 걷잡을 수 없어지기 전에 메서드 추출을 해서 적절한 길이의 메서드 여러개로 잘라낼 필요가 있음.
* 자바 코딩 규약
- http://www.oracle.com/technetwork/java/codeconventions-150003.pdf
- 위 문서의 9장 naming convention을 읽어보면 좋음.
- 그렇다고 해서 모든 프로젝트가 자바의 코딩 컨벤션을 따르지는 않음.
- 개발자끼리 코딩 규약을 만들어서 공유하는게 중요.
분류 코드를 클래스로 치환( Replace Type Code with Class) 리팩토링 (0) | 2020.01.28 |
---|---|
클래스 추출(Extract Class) 리팩토링 (0) | 2020.01.28 |
널 객체 도입 리팩토링 (0) | 2020.01.18 |
어서션(assert) 리팩토링 (0) | 2020.01.18 |
제어 플래그 삭제 (0) | 2020.01.08 |
댓글 영역