리팩토링 스터디 - 2. 리팩토링 원칙(2)

gimseonjin616·2022년 11월 20일
0

리팩토링

목록 보기
3/3

들어가며

이번 시간에는 지난 리팩토링 내용이 이어 챕터 2를 마저 정리하고자 한다.
이전 시간에는 리팩토링의 정의에 대해 살펴봤다면 이번 시간에는 리팩토링이 필요한 이유에 대해 설명한다.

리팩토링이 필요한 이유

이 책에서 제시하는 리팩토링의 이유는 크게 4개가 있다.

  1. 리팩토링을 하면 소프트웨어 설계가 좋아진다.
  2. 리팩토링을 하면 소프트웨어를 이해하기 쉬워진다.
  3. 리팩토링을 하면 버그를 쉽게 찾을 수 있다.
  4. 리팩토링을 하면 프로그래밍 속도를 높일 수 있다.

1. 리팩토링을 하면 소프트웨어 설계가 좋아진다.

완벽한 소프트웨어 설계는 없다. 상황에 따라 Best Practice는 바뀌기 마련이다. 예를 들면 아래와 같다.
(아래에서 언급하는 시드 단계는 임의로 예시를 든 거라 실제랑 맞지 않을 수 있다.)

A라는 회사가 있다. 이 회사가 시드 ~ 시리즈 A인 상황이라면 소프트웨어 설계는 MVP에 맞춰져 빠르게 기능을 검증하는 것에 초점을 맞춰야 한다. 그 후 시리즈 B ~ D 정도가 되면 기능 검증은 끝났다고 볼 수 있다. 따라서 사용자가 제대로 사용할 수 있도록 모니터링과 로그, 트래픽 폭증 대비에 포커스를 맞춰야 한다. 마지막으로 그 이상의 시리즈 단계가 되면 유지보수와 새로운 기능 확장이 쉽도록 관심사 분리 등에 집중해야한다.

각 단계마다 새로 소프트웨어를 설계할 수 없고 새로 만들 수 없다. 따라서 기존의 소프트웨어를 꾸준히 리팩토링해나가면서 소프트웨어를 발전시켜나가야 한다.

2. 리팩토링을 하면 소프트웨어를 이해하기 쉬워진다.

리팩토링은 결국 개발자가 코드를 읽기 쉽게 만드는 것이다. 읽기 쉬우면 코드를 이해하기 쉽다. 실제로 프로젝트를 하면서 리팩토링을 통해 코드 이해도를 높힌 경우가 있다.

DG Times라는 이름의 키워드 뉴스 검색 서비스를 만드는 프로젝트였다. 거기서 뉴스 검색 로직이 있었는데 mvp 검증을 위해 keyword 추출 방식의 검색 로직, Full Text Index를 사용한 검색 로직, 일반 LIKE 방식의 검색 로직 총 3개의 검색 로직을 구현했고 이 코드들이 섞여서 읽기가 매우 불편했다.

위 코드를 Strategy Pattern을 참고하여 리팩토링을 진행했고 한결 코드 읽기가 쉬웠으며 차후에 수정하기도 쉬웠다.

3. 리팩토링을 하면 버그를 쉽게 찾을 수 있다.

이 부분은 위 2번과 유사한 내용이다. 결국 소프트웨어를 이해할 수 있으면 관련해서 문제가 생길 수 있는 버그를 찾기 쉬운건 당연하다.

4. 리팩토링을 하면 프로그래밍 속도를 높일 수 있다.

처음 리팩토링을 접하면 '시간이 없는데 왜 코드를 정리해야하는 거지?? 시간이 없으니까 먼저 구현하고 리팩토링을 나중에 해야겠다' 라고 생각할 수 있다.

그러나 실제로 리팩토링을 먼저하고 나서 기능을 수정하는 것이 더 빠르게 프로그래밍을 할 수 있다.

위 그림은 리팩토링 책에서 제시하는 기능의 누적 - 시간 그래프 이다. 실제로 처음에는 좋은 설계가 나쁜 설계보다 시간이 더 오래 걸리지만 나중에 프로젝트가 진행되면 될수록 좋은 설계가 더 빠르게 기능을 구현할 수 있다는 내용이다.

따라서 리팩토링을 하여 설계를 계속 좋게 발전시켜나가면 그만큼 전체적인 프로그래밍의 속도가 높아진다는 내용이다.

리팩토링의 흐름

실제 책에서는 "언제 리팩토링해야 할까?" 라는 이름으로 되어있는데 나는 리팩토링의 흐름이라 표현하고 싶다.

이 흐름은 크게 3개의 단계가 있으며 1. 리팩토링 결정 -> 2. 리팩토링 종류 결정 -> 3. 리팩토링을 해선 안된다는 판단. 으로 되어있다.

1. 리팩토링 결정

책에서 제시하는 리팩토링 결정 규칙은 바로 3의 법칙이다.

  1. 처음에는 그냥한다.
  2. 비슷한 일을 두 번째로 하게 되면 일단 계속 진행한다.
  3. 비슷한 일을 세 번째 하게 되면 리팩토링 한다.

즉 코드 중복이 3번 발생하면 리팩토링을 하라는 가이드 라인이다.

그러나 나는 조금 다르게 다른 사람의 코드를 수정할 일이 있으면, 우선 리팩토링을 해보려고 노력한다!!! 왜냐면 그렇게 할 시, 그 사람이 작성한 코드의 이해도가 높아지게 되고 차후 코드 수정이 빨라질 수 있기 때문이다.

2. 리팩토링 종류 결정

리팩토링에는 여러 방식이 있다. 책에서 제시하는 종류는 5가지가 있다.

  1. 준비를 위한 리팩토링
  2. 이해를 위한 리팩토링
  3. 쓰레기 줍기 리팩터링
  4. 수시로 하는 리팩터링
  5. 오래 걸리는 리팩터링

각각의 리팩토링을 간단하게 정리해보고자 한다.

1. 준비를 위한 리팩토링

리팩토링을 하기 가장 좋은 시점은 새로운 코드를 추가하기 직전이다. 이때 코드를 살펴보며서 '이 부분을 이렇게 수정하면 새로운 기능을 추가하기 쉽겠네' 판단한다. 즉 준비를 위한 리팩토링은 새로운 기능 추가를 위해 준비하는 리팩토링이다.

2. 이해를 위한 리팩토링

개인적으로 이 리팩토링 방식을 열심히 써보려고 한다. 프로그래머로 일을 하다보면 내가 직접 코드를 짜는 것보다 다른 사람이 짜놓은 코드를 이해하는데 더 많은 시간을 보내게 된다. 그런 상황에서 리팩토링을 진행한다면, 예를 들어 코드의 의도가 명확한지, 조건부 로직의 구조가 이상하지 않은지, 함수 이름을 제대로 지었는지 확인한다. 이러한 과정을 통해 코드, 도메인의 이해도가 높아져서 더 빠르게 개발 및 수정을 진행할 수 있게 된다.

3. 쓰레기 줍기 리팩토링

만약 A 기능과 관련된 리팩토링을 진행한다고 하자, 이때 우연히 B와 관련된 비효율적인 코드를 발견했다고 하자, 그리고 이 코드를 수정하는데 오래 걸리지 않겠다 판단이 되면 그 코드를 수정하자!! 이것이 바로 쓰레기 줍기 리팩토링이다. 내가 A 기능을 리팩토링하고 있지만, 옆에 쓰래기(B와 관련된 기능의 비효율적인 코드)가 있는 것을 방치하면 그 프로그램에서는 악취가 계속 날 것이다.

4. 수시로 하는 리팩토링

리팩토링은 일정을 따로 잡지 않고 기능을 추가하거나 버그를 잡을 때 기회가 되면 한다! 즉 리팩토링을 프로그래밍 과정에 자연스럽게 녹인 것이다. 따라서 코드를 작성하거나 수정할 때 마다 '어? 이건 리팩토링하면 다음에 수정하기 쉽겠네?' 라는 생각이 들면 바로 바로 리팩토링을 진행할 수 있도록 한다.

5. 오래 걸리는 리팩토링

보통 리팩토링은 몇 분, 길면 몇 시간 정도면 끝낼 수 있다. 그러나 특정 케이스의 경우, 예를 들어 라이브러리를 다른 것으로 바꾼다던지, 일부 코드를 컴포넌트로 빼야한다던지의 경우에는 리팩토링이 오래 걸린다. 이러한 상황에서는 모든 팀이 리팩토링에 매달려 있는 것은 좋지 않다. 애시당초 리팩토링은 기존의 기능을 바꾸지 않으면서 코드를 수정해나가는 것이기 때문에 오래 걸리더라도 천천히 수정해나가는 방식으로 해야한다.

리팩토링을 하지 말아야 할 때!!

지금까지 챕터 2의 내용을 살펴보면 '리팩토링을 꼭 해!!'라는 내용처럼 들린다. 그러나 책에서는 리팩토링을 하면 안되는 케이스도 간단하게 언급한다. 예를 들어 악취가 나는 코드를 발견했지만 그에 대한 이해도가 떨어지거나 시급하지 않은 경우에는 리팩토링을 하지 않는다. 예를 들어 프론트엔드 개발자가 이전 개발자가 작성한 백엔드 코드 중에서 리팩토링이 필요한 코드를 발견했다고 하자, 그런 케이스에는 리팩토링을 진행하지 않는다. 왜냐하면 백엔드 로직에 대한 이해도가 낮고, 지금 당장 프론트 기능 구현하는데는 큰 영향을 끼치지 않기 때문이다.

또 다른 케이스로는 새로 만드는 것이 더 쉬울 경우에도 리팩토링을 하지 않느다. 물론 리팩토링이 더 쉬울지 새로 만드는 것이 더 쉬울지는 해보지 않고는 모르지만 다양한 경험과 판단력을 통해 잘 선택할 수 있도록 해야 한다.

정리

이번에 공부한 내용을 정리하면, 리팩토링의 필요성과 리팩토링을 언제, 어떻게 하는 것이 좋을까? 에 대한 기준을 얻을 수 있었다. 여기서 내가 얻은 것은 리팩토링은 좋은 코딩 습관이고 가능하다면 항상 할 수 있도록 하자!! 이다. 따라서 두 개의 모자(코딩용, 리팩토링용)를 자주 바꿔쓰면서 좋은 습관을 가지도록 노력하자!!!

profile
to be data engineer

0개의 댓글