(2) 리펙토링 방법
Two Hats (Refactoring then Adding Function)
전편에서 리팩토링의 개념에 대해 정리하였습니다. 리팩토링의 방법을 무조건 적용해야 좋은거이 아니라 협업 시 개발자간의 배려, 생산성 등을 위한 악취 제거입니다. 이번엔 어떻게 리팩토링을 하는지 방법에 대해 알아보겠습니다.
리팩토링(Refactoring) Step-by-Step
리펙토링을 하기위해서 2환경을 꼭 갖춘 상태에서 진행해야된다. 사실, 이 2가지는 리팩토링을 무관하고 개발을 하면서 반드시 준비해야되는 것들이다.
1) 테스트 프로그램 세팅
- 리팩토링은 기능을 유지하면서 코드를 개선하는 것이 목적이다.
- 리팩토링 후, 기능이 동일하게 작동하는지 확인하는 것은 당연한것.
- TDD 테스트 주도 개발과 함께 진행하면 좋음.
- Unit Test에서 자주 진행, Integration Test 에서도.
2) 확장 구조 만들기.
=> 새 기능을 추가하기 전에 기능을 추가하기 용이하게 개선 후, 추가하는 것이 효과적이다.
- 기능을 추가하면서 동시에 리팩토링을 하는것은 코드의 일관성, 컨벤션 룰에 방해되는 요소가 된다.
- 리팩토링 후 새 기능을 추가 할때 직전의 리팩토링 결과물을 고려하고, 적용한 방법들을 바로 적용 가능하므로 효율적이다.
=> 테스트 와 검증은 매우 중요!!
1. Extract Method
=> 긴 메소드의 일부 코드를 새 메소드로 만드는 것을 말한다.
- 이해를 위해, 주석을 이용해서 필요한 부분을 보통 분리한다.
- 메소드명은 짧고, 이 기능을 잘 설명할 수 있어야한다. (가독성, 재사용성 향상)
=> 반론. "한 번만 사용할 기능인데 메소드를 분리해야하나?", "다수 로직의 파편화는 디버깅이 힘들 수 있다!!"
- 일련의 과정을 Block 으로 관리.
=> 주의.
- Block 에는 주석이 항상 있어야 한다.
- 일련의 과정이 값 생성이라면, 해당 값은 상수 혹은 불변 자료구조이길 권장한다.
=> 결론. 주석에 쓴 내용은 매우 중요
긴 메소드의 코드를 맥락없이 block으로 나누는 것이 리팩토링이 아니다.
작은 기능, 일련의 과정 단위로 모듈화 하여 가독성을 위해 주석으로 분리하고, 명백히 나누어 짧고 분명한 이름의 새 메소드를 만든다.
2. Move Method
=> 한 메소드가 정의된 클래스의 위치가 적절한가?
- 객체의 상태를 전형 사용하지 않음. (정적 메소드를 고려. static)
- 다른 클래스에서 더 많이 사용할 경우. (책임 재분배. SRP)
=> Move Method 는 정의 위치(클래스)를 변경하는 리팩토링
- 기존 클래스에서는 위임호출로 유지하거나, 완전히 제거를 고려한다.
=> 결론. 불필요한 책임에 대한 재분배 필요!
3. 불필요한 임시변수 제거
=> 임시 변수는 대부분 메소드로 대체할 수 있다.
- 임시변수의 사용은 코드의 길이를 증가킬 수 있어 주의해야된다.
- 임시변수를 메소드화하면, 코드 길이 축소 및 재활용성에 좋다.
- 임시 변수 제거는 Extract Method 리팩토링을 수월하게 가능하다.
=> 반론. "Step-by-Step 에서 임시 상태를 저장은 디버깅 및 가독성에 좋을 수 있다!!"
- 임시변수를 사용할 경우, 임시변수가 아닌 상수로써 관리. 한번 할당된 값은 변경하지 말 것.
=> 결론. 코드 길이 축소도 좋지만, 유지보수성을 고려할 필요가 있다.
- 임시 상태를 사용하는 방법과 메소드로 대체하는 방법 2가지가 있다.
- 상황에 맞게 가독성, 디버깅 편의와 유지보수성과 코드 간소화에서 최적의 판단을 하여 적용하면 된다.
4. 분기 제거 Remove Control Flag
=> 일종 분기처리들은 조건의 추가 및 삭제에 유연하지 못하다.
=> 객체지향 개발에서는 이 분기들을 다형성으로 리팩토링할 수 있다.
Ex. 전략패턴으로 Code 속성에 따라 적절한 행위 수행이 가능하다.
=> 결론. 객체지향에서 IF 없이 코딩은 가능하지만, 적당한 선을 찾는 것이 중요하다.
- 무분별한 Control Flag는 소스코드에서 다중으로 중첩이 될 가능성이 높아 Performance에서 직간접적으로 영향을 줄 수 있으며, 가독성과 변경용이성을 보장할 수 없다.
- Control Flag를 사용을 금하는 것이 아닌 지양하여 최적의 선을 찾아 사용을 하거나 디자인 패턴 중 Strategy 패턴을 적용하여 행위를 클래스로 캡슐화해 동적으로 행위를 자유롭게 바꿔줄 수 있게 할 수 있다.