리팩토링의 개념
- 소프트웨어를 보다 쉽게 이해할 수 있도록 외부 동작을 바꾸지 않으면서 내부 구조를 개선하는 방법(이해하기 쉬운 코드가 수정하기도 쉬움)
리팩토링의 목적
- 소프트웨어를 보다 이해하기 쉽고, 수정하기 쉽도록 만드는 것
리팩토링을 하는 이유
- 유지 보수를 쉽게 하기 위해(코드를 이해하기 쉽고, 수정하기 쉽도록 하기 위해)
- 이해하기 쉽기 때문에 버그가 있다면 훨씬 쉽게 발견
- 코드의 중복을 제거 하여 수정하는데 쉬워짐
- 코드의 디자인을 유지하기 좋음
- 프로그램을 개발 생산성을 높이기 위해
리팩토링을 해야하는 시기
- 3진 아웃제(3번의 중복 / 3번의 같은 행위를 한다면 리팩토링을 진행하자!)
1 2 3 4
처음에는 그냥 개발한다. 두 번째 개발에 중복 코드가 나타나도 찜찜하지만 그냥 개발한다. 세 번째 개발에 중복 코드가 발생하면 이 때가 리팩토링할 때이다. (- 돈 로버츠, 마틴파울러의 동료)
- 두번째, 세번째 개발은 도대체 어떤 개발을 말하는 것인가?
- 기능을 추가할 때 리팩토링을 하자!
- 기능이 추가 되었다는 것은 언제든지 또 다른 기능이 추가 될 수 있다는 것이다. 이는 코드를 이해하기 쉽게 작성해야 함을 의미하며 즉시 리팩토링을 한다면 유지 보수 측면에서 더욱 효과적이다.
- 버그를 수정해야 할 때 리팩토링을 하라!
- 버그는 코드에 문제가 있기에 발생한다. 이 문제를 해결하기 위해선 코드를 쉽게 이해할 수 있도록 리팩토링이 필요하다. 또한 버그가 있었는데 미처 발견하지 못했다는 것은 그 코드가 가독성이 떨어짐을 의미하기도 하다.
- 코드 검토(Code Review)를 할 때 리팩토링을 하라!
- 개발자라면 자기만의 스타일이 존재하기 마련인데 이는 다른 사람은 읽기 힘들수도 있음을 뜻한다.
- 코드 리뷰는 내가 아닌 다른 사람들도 충분히 이해하기 쉬운 코드로 바꿀 수 있는 좋은 기회이다.
- 기능을 추가할 때 리팩토링을 하자!
리팩토링을 하면 안되는 시기
- 현재의 코드가 작동하지 않을 떄
- 마감일에 가까운 상황일 때
두 개의 모자
- 두 가지 구별된 작업(기능 추가와 리팩토링)을 위해 시간을 나눠야 함
- 기능을 추가할 때는 기존 코드를 건드려서는 안되고 단지 새로운 기능만 추가해야 함
- 리팩토링을 할 때는 기능을 추가해서는 안되고 단지 코드의 구조변경에만 신경써야 함
리팩토링 TIP
- Naming 중요성. 변수명, 클래스명, 메소드명 등 다른 사람들이 명확하게 인지할 수 있는 변수명을 사용하라!
- 클래스의 메소드는 클래스의 변수를 사용해야 함. 클래스의 정보를 사용하고 있지 않는다면 사용하고 있는 변수쪽으로 메소드는 움직여야 함
- 임시변수는 가능하면 제거하는 것이 좋음. 임시변수는 종종 쓸데없이 많은 파라미터를 만드므로 문제가 됨
- 임시변수를 하나의 메소드로 구현하여 리팩토링
- 리팩토링하는 과정에서 알고리즘적으로 성능이 더 안 좋아 질 수 있음. 하지만 어느 알고리즘 부분이 수정되어야 하는지 명확하게 보이게 되어 최적화하기 더 쉬운 형태로 변경되는 장점이 있음
- 다른 객체의 속성을 기반으로 한 switch문은 좋지않음. 그 부분을 함수로 추출하여 자신의 데이터를 사용하는 것으로 리팩토링해야함
- 메소드에서 두개의 클래스 변수를 사용하고 있다면 변화하기 쉬운쪽으로 메소드를 이동시켜 변화의 폭을 최대한 작게 해야함
- 기능이 한쪽으로 모여진 클래스를 추상화하여 상속관계로 표현할 수 있음
- [state 패턴 / strategy패턴] 상태를 나타내는가? 알고리즘을 나타내는가에 따라 이름이 바뀔 수 있음
- 테스트 -> 리팩토링 -> 테스트 -> 리팩토링 -> 테스트.. 점진적인 개선작업을 수행해야함
리팩토링과 디자인
- 리팩토링은 디자인을 보완하는 특별한 역할
- 프로그래밍을 하기 전에 미리 디자인에 대해 생각해보는 것이 비용이 많이 드는 재작업을 피하도록하는데 도움이 됨
1
시스템이 어떻게 돌아가는지 정확하게 알고 있다 하더라도, 추측만 하지 말고 실제로 퍼포먼스를 측정해보라. 무엇인가 배울 것이고, 십중팔구는 추측이 틀렸을 것이다.
리팩토링과 퍼포먼스
- 퍼포먼스는 중요한 부분
- 하지만 후반부에서 진행해야 할 부분이고 자주 사용하는 함수들 위주로 성능 최적화를 진행해야 함
- 그러기 위해서는 프로파일러를 통해 어느 부분이 Hot-spot인지 알아내기도 함
- 리팩토링을하는 동안 단기적으로는 소프트웨어를 느리게 하지만, 최적화 단계에서는 소프트웨어를 튜닝하는 것을 더 쉽게 함. 결국 이익이 됨