Chapter02. 리팩터링 원칙

김신영·2023년 7월 8일
1

Refactoring

목록 보기
2/12
post-thumbnail

리팩터링 정의

소프트웨어의 겉보기 동작은 그대로 유지한 채, 코드를 이해하고 수정하기 쉽도록 내부 구조를 변경하는 기법

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

두개의 모자 🧢

  • 소프트웨어를 개발할 때 목적이 기능 추가리팩터링이냐를 명확히 구분해야 한다.
    • 기능을 추가할 때는 기존 코드는 절대 건드리지 않고, 오로지 새 기능만 추가한다.
    • 리팩터링할 때는 기능 추가는 절대로 하지 않고, 오로지 코드 재구성에만 전념한다.

하지만 보통 소프트웨어를 개발하는 동안 두 모자를 자주 바꿔 쓴다….

리팩토링하는 이유

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

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

  3. 버그를 쉽게 찾을 수 있다.

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

언제 리팩터링해야 할까?

3의 법칙 3️⃣

  1. 처음에는 그냥 한다.

  2. 비슷한 일을 두 번째로 하게 되면, 일단 계속 진행한다.

  3. 비슷한 일을 세 번째 하게 되면 리팩터링한다.

준비를 위한 리팩터링

기능을 쉽게 추가하게 만들기

  • 리팩터링하기 가장 좋은 시점은 코드베이스에 기능을 새로 추가하기 직전이다.

이해를 위한 리팩터링

코드를 이해하기 쉽게 만들기

쓰레기 줍기 리팩터링

  • 간단히 수정할 수 있는 것은 즉시 고친다.
  • 시간이 좀 걸리는 일은 짧은 메모만 남긴 다음, 하던 일을 끝내고 나서 처리한다.

계획된 리팩터링 vs 수시로 하는 리팩토링

  • 보기 싫은 코드를 발견하면 리팩터링하자.
    • 그런데 잘 작성된 코드 역시 수많은 리팩터링을 거쳐야 한다.
  • 무언가 수정하려 할 때는 먼저 수정하기 쉽게 정돈하고(단, 만만치 않을 수 있다)
    • 그런 다음 쉽게 수정하자.
  • 계획된 리팩터링을 하게 되는 일은 최소한으로 줄여야 한다.
  • 리팩터링 작업 대부분은 드러나지 않게, 기회가 될 때 마다 해야한다.

⏳ 오래 걸리는 리팩터링

  • 팀 전체가 리팩터링에 매달리는 것은 추천하지 않는다.
  • 그보다는 주어진 문제를 몇 주에 걸쳐 조금씩 해결해가는 편이 효과적이다.
  • 누구든지 리팩터링해야할 코드와 과련한 작업을 하게 될 때마다 원하는 방향으로 조금씩 개선하는 방식이다.

🔎 코드 리뷰에 리팩터링 활용하기

  • Pair Programming 👍

❌ 리팩터링하지 말아야 할 때

  • 외부 API 다루듯 호출해서 쓰는 코드라면, 지저분해도 그냥 둔다.
    • 내부 동작을 이해해야할 시점에 리팩터링해야 효과를 제대로 볼 수 있다.
  • 리팩터링하는 것보다 처음부터 새로 작성하는 게 쉬울 때도 리팩토링하지 않는다.

리팩터링시 고려할 문제

새 기능 개발 속도 저하

리팩터링의 궁극적인 목적은 개발 속도를 높여서, 더 적은 노력으로 더 많은 가치를 창출하는 것이다.

  • ✅ 새 기능을 구현해 넣기 편해지겠다 싶은 리팩터링이라면 주저하지 않고 리팩터링부터 한다.
  • ❌ 반면 내가 직접 건드릴 일이 거의 없거나, 불편한 정도가 그리 심하지 않다고 판단되면 리팩터링하지 않는 편이다.

사람들이 빠지기 쉬운 가장 위험한 오류는 리팩터링을 클린 코드 나 바람직한 엔지니어링 습관처럼 도덕적인 이유로 정당화 하는 것이다.

  • 리팩터링하도록 이끄는 동력은 어디까지나 경제적인 효과에 있다.
  • ❌ 리팩터링의 본질은 코드 베이스를 예쁘게 꾸미는데 있지 않다.
  • ✅ 리팩터링은 개발 기간을 단축하고자 하는 것이다.

코드 소유권

  • 오픈소스 개발 모델

브랜치

  • Feature branch 방식에는 단점이 있다.
    • 독립 브랜치로 작업하는 기간이 길어질수록 마스터로 통합하기가 어려워진다.
  • CI에 따르면, 모든 팀원이 하루에 최소 한 번은 마스터 브랜치와 통합한다.
    • 다른 브랜치들과의 차이가 크게 벌어지는 일이 줄어들어 머지의 복잡도를 낮출수 있다.
    • 하지만, 마스터를 건강하게 유지하고, 거대한 기능을 잘게 쪼개는 법을 배우고, 각 기능을 끌 수 있는 feature toggle 혹은 feature flag 를 적용하여 완료되지 않은 기능이 시스템 전체를 망치지 않도록 해야 한다.

테스팅

  • 리팩터링의 두드러진 특성은 프로그램의 겉보기 동작은 똑같이 유지된다는 것이다.
  • 테스트 코드는 리팩터링을 할 수 있게 해줄 뿐만 아니라, 새 기능 추가도 훨씬 안전하게 진행할 수 있도록 도와준다.

레거시 코드

  • 제 기능과 맞지 않은 함수 이름을 바로 잡고, 어설픈 프로그램 구문을 매끄럽게 다듬어라.
  • ⚠️ 레거시 코드를 테스트 코드 없이 명료하게 리팩터링하기는 어렵다!
  • 서로 관련된 부분끼리 나눠서 하나씩 공략하는것을 추천한다.

데이터베이스

  • 데이터베이스 리팩터링은 프로덕션 환경에 여러 단계로 나눠서 릴리스하는 것이 대체로 좋다는 점에서 다른 리팩터링과 다르다.
    1. 필드 이름을 바꿀 때, 첫 번째 커밋에서는 새로운 데이터베이스 필드를 추가만 하고 사용하지 않는다.
    2. 그런 다음 기존 필드와 새 필드를 동시에 업데이트 하도록 설정한다.
    3. 그다음에는 데이터베이스를 읽는 크라이언트들은 새 필드를 사용하는 버전으로 조금씩 교체한다.
    4. 이 과정에서 발생하는 버그도 해결하면서, 클라이언트 교체 작업을 모두 끝냈다면, 예전 필드를 삭제한다.

리팩터링, 아키텍처, 애그니(YAGNI)

  • 유연성 메커니즘 (Flexibility Mechanism)
    • 향후 변경에 유연하게 대처
  • 현재까지 파악한 요구사항만을 해결
    • 진행하면서 요구사항을 더 잘 이해하게 되면, 그에 맞쳐서 리팩토링

YAGNI

you aren’t going to need it

  • 아키텍처와 설계를 개발 프로세스에 녹이는 방식
    • 리팩토링
  • 진화형 아키텍처 (Evolutionary Architecture)

리팩터링과 소프트웨어 개발 프로세스

XP (Extreming Programming)

익스트림 프로그래밍

  • 지속적 통합
  • TDD
    • 자가 테스트 코드
    • 리팩터링

리팩터링과 성능

  • 리팩터링하면 소프트웨어가 느려질 수도 있는건 사실이다.
  • 하지만, 그와 동시에 리팩터링하면 성능을 튜닝하기는 더 쉬워진다.
    • 성능 튜닝에 투입할 시간을 벌 수 있다.
      • 또한 프로파일링을 하면 이렇게 확보한 시간을 낭비 없이 쓸 수 있다.
    • 리팩터링이 잘 되어 있는 프로그램은 성능을 더 세밀하게 분석할 수 있다.
profile
Hello velog!

0개의 댓글