▶ 리팩토링(Refactoring)
1. refactoring 이란?
* 리팩토링은 외부 동작을 바꾸지 않으면서 내부 구조를 개선하는 방법으로, 소프트웨어 시스템을 변경하는 프로세스다.
* 디자인을 먼저 한 후 코드를 만드는 것이 아니라 일단 돌아가는 코드를 작성하고, 그 후에 그 코드가 더 좋은 구성을 갖도록 바꾼다는 것.
* 여러 곳에 산재된 중복 코드 정리
2. refactoring 하는 이유?
* 코드 간결성 및 가독성 증대
* 무엇인가 소스의 변경이 필요할 때(기능 추가나 삭제,수정 작업이 일어날 때) 소스의 리팩토링은 포장이사처럼 편하게 작업하도록 도와준다.
* 리팩토링은 소스의 중복된 부분을 모듈화 시켜준다. 모듈화는 입출력이 명확하기 때문에 이식성을 높여준다.
* 리팩토링을 통해 시스템 복잡도를 줄일 수 있다.
3. 활용
* coffeeList 조회 결과 coffee1 값이면 아메리카노, coffee2 값이면 카페라떼를 반환해주는 로직
* 기존: OriginalImpl.java 클래스 내 메소드 selectMenuList(), selectMenu(), updateMenu() 등에 소스 반복
* 활용: 여러 메소드 내에 반복되는 소스를 리팩토링 하여 하나의 메소드로 생성(convertCoffee(resultMap))
@Service("originalService") public class OriginalImpl implements OriginalService { public static final String AMERICANO = "coffee1"; public static final String CAFELATTE= "coffee2"; public static final String AMERICANO_VAL = "아메리카노"; public static final String CAFELATTE_VAL= "카페라떼";
// 메뉴리스트 조회 public List<Map<Stirng, Object>> selectMenuList() throws Exception {
...... List<Map<Stirng, Object>> resultList= originalDaoImpl.selectMenuList(); String coffee= resultList .get("coffee").toString();
if(coffee.equalsIgnoreCase(AMERICANO)) { coffee = AMERICANO_VAL; } else if (coffee.equalsIgnoreCase(CAFELATTE)) { coffee = CAFELATTE_VAL; } else { throw new DataFormatException(); } resultList.put("coffee", coffee); ...... }
// 메뉴 조회 public Map<String,Object> selectCoffee() throws Exception { ......
Map<String,Object> resultMap = originalDaoImpl.selectMenu(); String coffee= resultMap .get("coffee").toString();
if(coffee.equalsIgnoreCase(AMERICANO)) { coffee = AMERICANO_VAL; } else if (coffee.equalsIgnoreCase(CAFELATTE)) { coffee = CAFELATTE_VAL; } else { throw new DataFormatException(); } resultList.put("coffee", coffee); ...... } // 메뉴 업데이트 public Map<Stirng, Object> updateMenu() throws Exception { ...... // 메뉴 업데이트 후 메뉴 조회 서비스 (업데이트 반영) Map<String,Object> resultMap = originalDaoImpl.selectMenu(); String coffee= resultMap .get("coffee").toString();
if(coffee.equalsIgnoreCase(AMERICANO)) { coffee = AMERICANO_VAL; } else if (coffee.equalsIgnoreCase(CAFELATTE)) { coffee = CAFELATTE_VAL; } else { throw new DataFormatException(); } resultList.put("coffee", coffee); ...... } |
위의 코드에 주황색으로 표시 된 부분이 여러 method에서 반복되고 있는 소스다.
반복되는 소스는 시스템 복잡도를 높일 뿐만 아니라 소스에 변경사항이 발생하는 경우 해당 소스를 포함하고 있는 각 메소드 마다
일일이 수정해줘야하는 번거로움이 생긴다.
이러한 문제를 해결하기 위해 아래와 같이 리팩토링을 한다.
* 반복되는 소스 전체 선택 후 우클릭 > Refactor > Extract Method 선택
* Method 명 설정
// extract method 결과 - convertCoffee(Map<String, Object> resultMap) 생성 private void convertCoffee(Map<String, Object> resultMap) throws DataFormatException { String coffee= resultMap .get("coffee").toString();
if(coffee.equalsIgnoreCase(AMERICANO)) { coffee = AMERICANO_VAL; } else if (coffee.equalsIgnoreCase(CAFELATTE)) { coffee = CAFELATTE_VAL; } else { throw new DataFormatException(); } resultMap.put("coffee", coffee); } // 메뉴리스트 조회 public List<Map<Stirng, Object>> selectMenuList() throws Exception { ...... List<Map<Stirng, Object>> resultList= originalDaoImpl.selectMenuList(); resultList = convertCoffee(resultList); ...... } // 메뉴 조회 public Map<String,Object> selectCoffee() throws Exception { ......
Map<String,Object> resultMap = originalDaoImpl.selectMenu(); resultMap = convertCoffee(resultMap); ...... } // 메뉴 업데이트 public Map<Stirng, Object> updateMenu() throws Exception { ...... // 메뉴 업데이트 후 메뉴 조회 서비스 (업데이트 반영) Map<String,Object> resultMap = originalDaoImpl.selectMenu(); resultMap = convertCoffee(resultMap); ...... } |
convertCoffee 라는 method를 생성함으로써 각 method에서는 얘를 호출하여 coffee 명을 가져올 수 있게 된다.
기존 코드보다 훨씬 간결해진 모습을 확인할 수 있다. (주황색 부분이 파란색 부분으로 변경됨!)
나같은 경우도 처음에는 각 method마다 동일 소스를 계속 반복하여 사용했었다..'재활용성'에 대한 개념이 아예 없었다.
다행히 리팩토링은 처음부터 적용하려는 의도로 나온 애가 아니라, 소스코드 작성 후 코드 품질 최적화를 위해
적용할 수 있는 부분에 쓰는 애다. ㅎㅎ 물론 미리 알고 썼더라면, 리팩토링하는 시간도 줄었겠지만.... 앞으로 잘쓰면 되지~~
처음엔 반복되는 코드를 작성했었더라도 이제 리팩토링 개념과 효과를 알았으니 내 코드 최적화를 위해
리팩토링을 요리조리 잘 써먹어야 겠다.
이번 포스팅에는 리팩토링의 정말 기본 내용만 담고 있지만, 앞으로 리팩토링 해보면서 좀 더 깊이 있게 쓰게되면
리팩토링 2.0 버전으로 새 글 리포팅해야겠다 :)
__________________________________________________________________________________________________________________________________________________________
** 본 포스팅에 대해 수정해야할 부분이나 추가 의견 등이 있으신 분들은 댓글 달아주세요. 언제나 환영입니다 :)
** 본 포스팅은 아래의 reference 들을 참고하여 내용을 덧붙인 글입니다. 혹시, 문제가 되는 경우 알려주시면 조치하도록 하겠습니다.
- http://belong2jesus.tistory.com/62
- http://www.zdnet.co.kr/news/news_view.asp?artice_id=00000039161606&type=det&re=
'JAVA' 카테고리의 다른 글
예외처리 관련 참고문서 (0) | 2017.06.11 |
---|---|
로깅(Logging) 참고문서 (0) | 2017.06.11 |
JAVA - 향상된 for 문 (from Java1.5) (0) | 2017.02.26 |
system32와 systemWOW64 (0) | 2017.02.26 |
SAPJCO 연동 설정 (0) | 2017.02.26 |