logo
새로운 블로그로 이전하였습니다.

(리팩터링 2판) ch02. 리팩터링 원칙

  • 리팩터링
  • refactoring
  • js
  • 마틴파울러
  • 리팩터링원칙

👷🏻 두 개의 모자

켄트 백의 말에 따르면, 코드를 짤 때 아래 두 개의 모자들 중 하나를 쓰고 작업한다고 한다.

1. 👒 기능 추가 모자

  • 기능을 추가 시에는 기능 추가 모자 를 쓴 후, 기존 코드는 절대 건드리지 않고 새 기능을 추가하기만 한다.
  • 진척도는 테스트를 추가해서 통과하는 지 확인하는 방식으로 측정한다.

2. 🎩 리팩토링 모자

  • 리팩터링할 때는 리팩토링 모자 를 쓴 후, 기능 추가 없이, 오로지 코드 재구성에만 전념한다.
  • 테스트도 새로 만들지 않는다. (앞에서 놓친 테스트 케이스를 발견하거나 부득이 인터페이스를 변경해야할 때는 예외로 한다.)

아무리 짧은 시간동안 작업을 한다고 해도, 항상 본인이 무슨 모자를 쓰고 있는 지 인식하고, 그에 따른 미묘한 작업 방식의 차이를 분명하게 인식하면서 개발해야 한다.

나의 생각



🧐 리팩터링하는 이유

소프트웨어 설계가 좋아진다

  • 리팩터링하지 않으면 소프트웨어의 내부 설계(아키텍쳐)가 썩기 쉽다.
  • 아키텍처를 충분히 이해하지 못한 채 단기 목표만을 위해 코드를 수정하다보면 기반 구조가 무너지기 쉽다. 이로 인해 코드만 봐서는 설계를 파악하기 어려워지고, 설계 유지가 어려워지며, 중복 코드가 발생한다.
  • 중복 코드 제거로 코드량이 줄면, 코드를 수정하는 데 드는 노력이 줄어진다.
  • 모든 코드가 언제나 고유한 일을 수행함을 보장할 수 있다. (바람직한 설계의 핵심!)

소프트웨어를 이해하기 쉬워진다

  • 프로그램을 동작시키는 데만 신경 쓰다 보면 나중에 코드를 다룰 개발자(미래의 나 혹은 다른 개발자)를 배려하지 못하게 된다.
  • 코드의 목적이 더 잘 드러나게 리팩토링한다면, 코드가 더 잘 읽힌다.

버그를 찾기 쉬워진다

  • 리팩터링하면 코드가 하는 일을 깊이 파악하게 되면서 새로 깨달은 것을 곧바로 코드에 반영할 수 있다.
  • 프로그램의 구조를 명확하게 다듬으면 그냥 ‘이럴 것이다’라고 가정하던 점들이 분명히 드러나, 버그를 잘 찾을 수 있게 된다.

⭐ 프로그래밍 속도를 높일 수 있다

  • 새로운 기능을 추가할 수록 기존 코드베이스에 잘 녹여낼 방법을 찾는 데 드는 시간이 늘어난다. 기능 추가 후에는 버그가 더 잦게 발생하고, 이를 디버깅하는 데 더 많은 시간이 소요된다.
  • 코드베이스는 패치에 패치가 덧붙여지면서 프로그램의 동작을 파악하기가 거의 고대 유적 발굴만큼 어려워진다.
  • 내부 설계가 잘 된 소프트웨어는 새로운 기능을 추가할 지점과 디버깅하는 방법을 쉽게 찾을 수 있다.

리팩터링 시 고려할 문제 중 브랜치에 관해

기능 브랜치

버전 관리 시스템을 사용해 팀원마다 코드베이스의 브랜치를 하나씩 맡아서 작업하다가, 결과물이 어느 정도 쌓이면 메인 브랜치에 통합해서 다른 팀원과 공유하는 것

단점

  • 독립 브랜치로 작업하는 기간이 길어질 수록 작업 결과를 메인으로 통합하기 어려워진다.
  • 보완법: 이를 보완하기 위해 메인을 개인 브랜치로 수시로 리베이스 혹은 머지한다.
  • 보완법의 한계 : 하지만 여러 기능 브랜치에서 동시에 개발이 진행될 때는 한계가 있다.

머지 vs 통합

** 추가 단점들과 보완법 **

  • 누군가 개인 브랜치에서 작업한 내용을 메인에 통합하기 전까지는 다른 사람이 그 내용을 볼 수 없다. 통합한 뒤에는 메인에서 달라진 내용을 내 브랜치에 머지해야하는데, 상당한 노력이 든다.
  • 최신 버전 관리 시스템은 복잡한 변경 사항을 텍스트 수준에서 머지하는 데는 매우 뛰어나지만, 코드의 의미는 전혀 이해하지 못한다.
  • 머지가 복잡해지는 문제는 기능별 브랜치들이 독립적으로 개발되는 기간이 길어질 수록 기하급수적으로 늘어난다. ex) 4주간 작업한 브랜치들을 통합하는 노력은 2주간 작업한 브랜치들을 통합할 때보다 두 배 이상 든다.
  • 위와 같은 문제를 방지하기 위해 기능별 브랜치의 통합 주기를 2일보다 더 짧게 가져가는 것을 CI 혹은 TBD라고 한다.

지속적 통합 (CI)과 리팩토링

지속적 통합 (CI)이란?

  • 모든 팀원이 하루에 최소 한 번은 메인과 통합한다.

CI의 장점

  • 리팩터링과의 궁합이 좋다.
  • 머지의 복잡도를 낮출 수 있다.

CI 적용 요건

  • 메인을 건강하게 유지해야 한다.
  • 거대한 기능을 잘게 쪼개는 법을 배워야 한다.
  • 각 기능을 끌 수 있는 기능 토글을 적용하여 완료되지 않은 기능이 시스템 전체를 망치지 않도록 해야 한다.

CI를 적용하지 못하더라도 기능별 브랜치를 사용한다면

통합 주기만큼은 최대한 짧게 잡는 것이 좋다.


💬 기억하고 싶은 부분

누군가 “리팩터링하다가 코드가 깨져서 며칠이나 고생했다”라고 한다면, 십중팔구 리팩터링한 것이 아니다. - 80p

리팩터링은 성능 최적화와 비슷하다. 둘 다 코드를 변경하지만 프로그램의 전반적인 기능은 그대로 유지한다. 단지 목적이 다를 뿐이다. 리팩터링의 목적은 코드를 이해하고 수정하기 쉽게 만드는 것이다. - 80p