Search

Chapter 02

리팩토링을 해야하는 이유

소프트웨어 설계가 개선된다.
구조가 산만해진 코드를 정리하는 작업
부적절한 위치에 있는 코드를 제거하는 것
보통 기능이 같은 코드가 여기저기 중복되어 있어서 쓸데 없이 코드가 길어진다.
소프트웨어를 이해하기가 더 쉬워지니까
낯선 코드를 쉽게 이해할 수 있다.
버그를 찾기 쉬워진다.
프로그래밍 속도가 빨라진다.
설계가 깔끔하지 않으면 초기에는 진행이 빠를 수도 있는데, 나중에 가면 속도가 느려진다.
새 기능을 넣으려면 원래의 코드를 반복적으로 패치해야해서 코드가 길어질 수 밖에 없다.

리팩토링은 어떨 때 필요한가

같은 작업의 삼진 아웃 때
기능을 추가할 때
소프트웨어에 새 기능을 추가할 때
설계가 지저분해서 기능을 추가하기 힘들 때
버그를 수정할 때
이해하기 힘들면 이해하기 쉽게 만드려고 리팩토링을 실시
코드를 검수할 때

4가지 상황일 때 수정하기 힘들어진다.

코드를 알아보기 힘들 때
중복된 로직이 들어 있을 때
추가 기능을 넣어야 해서 실행 중인 코드를 변경해야 할 때
조건문 구조가 복잡할 때

리팩토링 관련 문제들

데이터베이스
데이터베이스 스키마와 강력히 결합되어있다.
데이터베이스 스키마를 수정하면 데이터도 이전해야하는데, 위험성이 높다.
객체 모델과 데이터베이스 모델 사이에 별도의 소프트웨어 계층을 두는 방법이 있다.
중개 계층이 생기면 복잡하긴 하지만, 상당한 유연성이 생긴다.
객체 모델의 일정 부분들이 변경될 가능성이 높다는 사실을 깨달았을 때 별도의 계층을 생성하면 된다.
인터페이스 변경
인터페이스를 건드리지 않고 내부의 구현 코드를 수정할 수 있다는 점.
하지만 상당수의 리팩토링이 인터페이스를 건드린다.
메서드를 사용하는 모든 코드에 접근할 수 있다면, 메서드명을 변경하는 것은 문제가 되지 않는다. 인터페이스가 사용되는 부분을 찾는게 불가능하거나 수정할 수 없을 땐 문제가 생김.
이럴 경우, 인터페이스를 사용하는 부분이 그 인터페이스 변경에 맞춰 수정되기 전까지는 기존 인터페이스와 새 인터페이스를 모두 그대로 유지시켜야한다. 기존 인터페이스가 새 인터페이스를 호출하게 하면 된다.
deprecation 타입을 작성해서 사용하지 않도록 해야함.
내가 접근할 수 있는 코드들 안에서만 사용하는 인터페이스 말고, 내가 접근할 수 없는 코드들에서 이 인터페이스를 호출하는 경우 published 인터페이스라고 하는데, 이런 경우를 지양하는게 좋다. 인터페이스를 수정하기 어렵기 때문이다.

리팩토링하면 안되는 상황

납기가 임박했을 때
언제나 시간에 쫓길 때

리팩토링과 설계

설계를 하면 생각이 아주 빨라지지만 그 생각엔 빈틈이 많다.
따라서 일단 머릿속 아이디어를 코딩하고 잘 돌아가게 만든 후, 그것을 리팩토핑으로 세밀히 다음어야 한다.
문제는 리팩토링으로 인해 사전 설계의 역할이 변한다는 것이다. 리팩토링하지 않을 때는 사전 설계를 정확히 해야 한다는 부담감이 크다. 나중에 설계를 수정하려면 큰 비용이 들기 때문. 나중에 수정할 필요가 없도록 사전 설계에 더 많은 시간과 큰 노력을 들여야 한다.
리팩토링을 실시하면 중점적인 작업이 달라진다. 여전히 사전 설계를 하지만, 완벽하게 할 필요가 없고 그냥 적당히 하면 된다. 솔루션을 구축해나가면서 문제를 더 잘 이해하게 되고, 리팩토링을 실시하면 수정 비용도 드는 것이 아니다.
장점: 설계가 단순해진다.
매번 유연한 솔루션을 찾아 해맸고, 어떤 필요사항이든 그것이 얼마나 유지될지 늘 궁금함. 설계 수정엔 큰 비용이 드니까 향후 뻔히 하게 될 수정에도 영향을 받지 않는 설계를 구축하고자 함.
⇒ 유연하고, 당초 계획대로 구현하긴 쉽지만, 복잡하고 유지보수 하기 어렵다.
사실 시스템 전체를 유연하게 할 필요는 없다. 유연성이 필요한 곳은 일부이고, 그나마 그런 부분이 어딘지를 예측하는 것도 불가능함.
리팩토링을 실시하면 유연성을 낮추지 않고도 간결하게 설계가 가능함. 필요할 때만 리팩토링하기 때문에