imgyuzzzang

[리팩터링 2판] 리팩토링 기본 및 원칙, 안티패턴 정리해보자! 본문

book

[리팩터링 2판] 리팩토링 기본 및 원칙, 안티패턴 정리해보자!

imgyuzzzang 2023. 2. 23. 23:48

티하 (티스토리 하이..^~^)

드디어....!! 리팩터링 2판을 다 읽고 정리 공유하러 컴백 후후

 

내용 중에 당연한 부분도, 공감되는 부분도 있지만

너무 옛날 책이라 오잉 이건 좀 별론데 하는 부분도 있었다.

특히 나는 JS 함수형으로 쓰는걸 좋아하는 사람인디

저자는 OOP 러버이신 것 같았다... 후후

끝으로 갈수록 결국 클래스 어떻게 상속하고 어떻게 쓸지 이런거에 집중되는 너낌

 

총 12 챕터로 되어있고 너무 길어서 두 번에 걸쳐서 포스팅 예정

오늘은 1~6 챕터 내용 정리해보가쓰 (5챕터는 내용 없어서 skip)

챕터 제목은 책과 다를 수 있는데, 이유는 너무나도 번역체여서 대충 내 말로 바꿔봤당 유후

중간 중간 회색은 그냥 내 생각 껴놓기 

 

 

Chapter #1 리팩터링 첫 번째 예시

  • 프로그램 기능 확장 시 초기 설계된 개발 구조와 맞지 않을 가능성이 매우 높음.
  • 새로운 기능 추가 시 추가하기 쉬운 형태로 리팩토링 후 추가하기
  • 리팩터링 단계
    1. 리팩터링 코드 영역 검사하기 위한 테스트 코드(자가진단 가능하게)
    2. 함수 추출 ( 매번 코드를 분석해서 얻은 정보 → 휘발성이 높으므로 빨리 읽기 쉽게 함수화)
    3. 변경 후 테스트
    • 핵심은 찔끔 변경 후 테스트 반복!
  • 함수 내부 정리 과정에서 나온 적용해볼 만한 규칙
    • 함수 반환값 변수는 항상 result
    • 타입 + 매개변수이름으로 변수명 작성→ 이건 ts 쓰면 별로 필요하진 않을 듯? 옛날 책이라 요즘이랑 안 맞는게 좀 있는 것 같다
    • 임시변수 최대한 제거(함수의 두 파라미터가 한 파라미터에 의해 결정될 때 등) → 함수 추출 작업 용이
      • 함수변수 → 일반함수로
  • 결국 리팩토링을 진행하면 중복 호출, 반복문 쪼개기 등으로 성능이 느려지는 이슈 발생할 수 밖에 없다 ...!

but 실제 성능에는 큰 영향 x, 영향이 있더라도 리팩터링 후 성능 개선 더 효과적으로 수행 가능하다고 봄!

 

Chapter #2 리팩토링 원칙

  • 리팩토링?
    • 겉보기 동작 유지 + 코드이해 및 수정 용이하게 내부 구조 변경
    • 핵심은 동작 보존! 리팩터링 동안에는 코드가 항상 정상 작동
    • 그래서 테스트가 중요하다! 계속 기능 보존하는지 봐줘야해
  • 리팩토링 할 땐 코드 구조 개선만, 기능 추가할 때는 기능 추가만! 한번에 하려 하지 말기
    • 내가 제일 못 하는거 ^^,, 개선하다 보면 오류도 보이고 한 커밋에 refactor + fix 섞이면 진짜 구려진다
  • 리팩토링하는 이유?
    • 설계가 좋아짐 + 이해하기 쉬움 + 버그 찾기 쉬움 + 프로그래밍 속도 증진
  • 팀 단위로, 기간을 오래잡고 하는 리팩토링은 bad, 간단한 기능 추가 직전이나 코드 리뷰에서 진행 good
    • feat 커밋 전에 refactor로 시작하는 습관을 들여볼까나,, 맨날 얜 구조가 왜이래 투덜댔지만 내가 고쳐서 쓰자!
    • 이전엔 기간 오래잡고 우다다 하는게 리팩토링인 줄 알았다. 
    • 예를 들어 jquery -> react 는 마이그레이션이지 이 책에서 정의하는 리팩토링은 아닌 것 같다
  • 리팩토링의 궁극적인 목적은 개발 기간을 단축하기 위함!
    • 코드 베이스를 예쁘게 꾸미는 데에 x
    • 기능 추가시간 줄이기, 버그 수정시간 줄이기 등
  • 과도한 확장성 고려는 비용이 너무 클 수 있음 → 현재 요구사항 완벽히 설계 + 점진적 설계하기
  • TDD + CI + 리팩토링 → 강력한 상승효과
  • 성능 vs 직관적 설계(읽기 좋은 코드) ?
    • 성능 이슈는 대부분 프로그램의 아주 일부 구조로 인해 발생 → 90%의 디버깅은 시간낭비
    • 리팩토링 이후 성능 튜닝 더 쉽고 빠르게 하기 추천

 

Chapter #3 다양한 안티 패턴 잡기!

  • 모호한 변수명 → 단순 명료하게
  • 중복 코드 → 함수 추출
  • 긴 함수 → 짧은 함수로 추출 + 함수명 명료하게
  • 너무 많은 매개변수 → 객체 통째로 넘기기 or 여러 함수 클래스로 묶기 or 매개변수를 질의 함수로
  • 전역 데이터 → 변수 캡슐화
  • 가변 데이터 → 용도별 독립 변수 or 변수 캡슐화
  • 단일 책임x (한 코드에 여러 모듈)→ 단계 쪼개기, 함수 추출
  • 단일 책임x (한 모듈 여러 코드에 흩어진)→ 여러 함수를 클래스로 묶기
  • 함수의 특정 기능 편애(타 모듈의 데이터와 상호작용 더 많이 함) → 옮겨주기
  • 묶이지 않은 데이터 뭉치 → 클래스 추출, 매개변수 객체 생성
  • 기본형 변수 집착 → 객체로 바꾸기
  • switch문 반복 → 조건부 로직을 다형성으로 바꾸기
  • 반복문 → pipline
  • 불필요한 요소(클래스에 메소드 하나 이런 식) → 제거작업(인라인)
  • 사용되지 않는 과도한 확장성 고려 → 추상 클래스, 안쓰는 위임 코드 계층 합치기, 코드 삭제
  • 임시필드 → 대안 클래스 생성 or 클래스 추출
  • 메시지 체인(a.b.c.d… 이런식으로 쓰는) → a.d등 더 짧고 직관적으로 호출할 수 있게 연결
  • 위와 반대 상황으로 과도한 중개자 → 중개자 제거하기
  • 이 외에도 너무 큰 클래스, 너무 장황한 주석 등도 클래스 또는 함수를 쪼개는 방식으로 해결 가능

 

Chapter #4 테스트 구축

  • 자가 테스트 코드 + 테스트 자주 수행 → 버그 찾는 강력한 도구
  • 위험 요인에 집중하여 테스트 (public 메서드 등.. )
  • 테스트끼리 상호 작용하는 공유 픽스처를 만들지 않기.
    • 테스트 순서에 따라 결과가 제멋대로일 수 있음
    • 최대한 서로 독립적으로 수행될 수 있도록 작성
  • 경계 조건 위주로 테스트 코드 잘 짜기!
  • 테스트 커버리지는 테스트하지 않은 코드영역 찾는 데엔 도움이 되지만 테스트 품질과는 사실 큰 상관 x

 

Chapter #5 리팩터링 카탈로그 보는 법

  • 정리 생략^^

 

Chapter #6 기본적인 리팩토링

  • 함수 추출
    • 함수가 무슨 일을 하는지 파악하는 데 한참 걸린다면 목적을 드러내도록 추출 (어떻게x 무엇을o)
    • 리팩토링하는 순서는 다음과 같다 
      • 함수명작명 → 추출 코드 복붙 → 지역변수, 유효범위 벗어나는 변수 확인 → 매개변수 전달 → 컴파일 → 원본함수에서 새 함수 호출하도록 변경 → 테스트
      • 리팩토링 과정에서도 원래 기능이 계속 작동할 수 있게 + 끊임없는 테스트가 핵심
  • 함수 인라인
    • 함수를 불필요하게 너무 잘게 쪼개놨다면 합쳐야 할 수도
    • 다형 메서드 체크(오버라이드는 인라인하면 x) → 인라인 함수 호출문을 함수 본문으로 교체 → 테스트 → 함수삭제
  • 변수 추출
    • 표현식 너무 복잡해지면 지역 변수 사용하여 표현식 쪼개서 이름 붙이기
    • 변수 추가를 통해 주석 내용이 코드에 포함되면 주석은 삭제해주기
  • 변수 인라인
    • 변수 이름이 표현식과 다를 바 없을 때 인라인 하기
  • 함수명 변경
    • 이름 정하기 어렵다면? 주석을 이용해 함수 목적 설명해보기 → 정리해서 이름으로!
    • 매개변수 추가 등을 할때도 새 함수 만들기 → 기존 함수에서 새함수 호출하기 → 테스트 → 기존함수 제거
  • 변수 캡슐화: setter, getter 통해서 변수 접근하게 하기
  • 변수 이름 변경
  • 매개변수 객체 만들기(자주 붙어다니는 무리): 함수 호출 시에도 객체로 호출
  • 여러 함수를 클래스로 묶기: 중첩함수도 가능하긴 한데, 테스트가 까다로울 수 있음, 최상단 함수일 경우
  • 여러 함수를 변환 함수로 묶기
    • 같은 도출 로직이 반복될 때 사용
    • 가공 데이터를 새로운 레코드로 저장하여 반환
  • 단계 쪼개기
    • 서로 다른 두 대상을 한꺼번에 다루는 경우 각각 모듈로 나누기

 

리팩토링 방법으로 서로 반대되는 개념을 함께 소개하면서, 한가지 방법론에 매몰되어 과도하게 코드를 분해하는게 아니라 적절한 정도로 구조를 개선해야한다는 것이 잘 전달된 듯

 

Comments