리팩토링을 해야하는 이유
•
소프트웨어 설계가 개선된다.
◦
구조가 산만해진 코드를 정리하는 작업
◦
부적절한 위치에 있는 코드를 제거하는 것
◦
보통 기능이 같은 코드가 여기저기 중복되어 있어서 쓸데 없이 코드가 길어진다.
•
소프트웨어를 이해하기가 더 쉬워지니까
◦
낯선 코드를 쉽게 이해할 수 있다.
•
버그를 찾기 쉬워진다.
•
프로그래밍 속도가 빨라진다.
◦
설계가 깔끔하지 않으면 초기에는 진행이 빠를 수도 있는데, 나중에 가면 속도가 느려진다.
◦
새 기능을 넣으려면 원래의 코드를 반복적으로 패치해야해서 코드가 길어질 수 밖에 없다.
리팩토링은 어떨 때 필요한가
•
같은 작업의 삼진 아웃 때
•
기능을 추가할 때
◦
소프트웨어에 새 기능을 추가할 때
◦
설계가 지저분해서 기능을 추가하기 힘들 때
•
버그를 수정할 때
◦
이해하기 힘들면 이해하기 쉽게 만드려고 리팩토링을 실시
•
코드를 검수할 때
4가지 상황일 때 수정하기 힘들어진다.
•
코드를 알아보기 힘들 때
•
중복된 로직이 들어 있을 때
•
추가 기능을 넣어야 해서 실행 중인 코드를 변경해야 할 때
•
조건문 구조가 복잡할 때
리팩토링 관련 문제들
•
데이터베이스
◦
데이터베이스 스키마와 강력히 결합되어있다.
◦
데이터베이스 스키마를 수정하면 데이터도 이전해야하는데, 위험성이 높다.
◦
객체 모델과 데이터베이스 모델 사이에 별도의 소프트웨어 계층을 두는 방법이 있다.
◦
중개 계층이 생기면 복잡하긴 하지만, 상당한 유연성이 생긴다.
◦
객체 모델의 일정 부분들이 변경될 가능성이 높다는 사실을 깨달았을 때 별도의 계층을 생성하면 된다.
•
인터페이스 변경
◦
인터페이스를 건드리지 않고 내부의 구현 코드를 수정할 수 있다는 점.
◦
하지만 상당수의 리팩토링이 인터페이스를 건드린다.
◦
메서드를 사용하는 모든 코드에 접근할 수 있다면, 메서드명을 변경하는 것은 문제가 되지 않는다. 인터페이스가 사용되는 부분을 찾는게 불가능하거나 수정할 수 없을 땐 문제가 생김.
◦
이럴 경우, 인터페이스를 사용하는 부분이 그 인터페이스 변경에 맞춰 수정되기 전까지는 기존 인터페이스와 새 인터페이스를 모두 그대로 유지시켜야한다. 기존 인터페이스가 새 인터페이스를 호출하게 하면 된다.
◦
deprecation 타입을 작성해서 사용하지 않도록 해야함.
◦
내가 접근할 수 있는 코드들 안에서만 사용하는 인터페이스 말고, 내가 접근할 수 없는 코드들에서 이 인터페이스를 호출하는 경우 published 인터페이스라고 하는데, 이런 경우를 지양하는게 좋다. 인터페이스를 수정하기 어렵기 때문이다.
리팩토링하면 안되는 상황
•
납기가 임박했을 때
•
언제나 시간에 쫓길 때
리팩토링과 설계
설계를 하면 생각이 아주 빨라지지만 그 생각엔 빈틈이 많다.
따라서 일단 머릿속 아이디어를 코딩하고 잘 돌아가게 만든 후, 그것을 리팩토핑으로 세밀히 다음어야 한다.
문제는 리팩토링으로 인해 사전 설계의 역할이 변한다는 것이다. 리팩토링하지 않을 때는 사전 설계를 정확히 해야 한다는 부담감이 크다. 나중에 설계를 수정하려면 큰 비용이 들기 때문. 나중에 수정할 필요가 없도록 사전 설계에 더 많은 시간과 큰 노력을 들여야 한다.
리팩토링을 실시하면 중점적인 작업이 달라진다. 여전히 사전 설계를 하지만, 완벽하게 할 필요가 없고 그냥 적당히 하면 된다. 솔루션을 구축해나가면서 문제를 더 잘 이해하게 되고, 리팩토링을 실시하면 수정 비용도 드는 것이 아니다.
장점: 설계가 단순해진다.
매번 유연한 솔루션을 찾아 해맸고, 어떤 필요사항이든 그것이 얼마나 유지될지 늘 궁금함. 설계 수정엔 큰 비용이 드니까 향후 뻔히 하게 될 수정에도 영향을 받지 않는 설계를 구축하고자 함.
⇒ 유연하고, 당초 계획대로 구현하긴 쉽지만, 복잡하고 유지보수 하기 어렵다.
사실 시스템 전체를 유연하게 할 필요는 없다. 유연성이 필요한 곳은 일부이고, 그나마 그런 부분이 어딘지를 예측하는 것도 불가능함.
리팩토링을 실시하면 유연성을 낮추지 않고도 간결하게 설계가 가능함. 필요할 때만 리팩토링하기 때문에