02. 리팩터링 원칙
#
느낀점리팩터링의 궁극 적인 목적은 개발 속도를 높여, 더 적은 노력으로 더 많은 가치를 창출 하는 것
- 위 명언을 계속 리마인드하자
- 토이플젝 하는 곳에서 안정적으로 리팩터링하기 위해서라도 jenkins + PR 테스팅 (CI) 를 구성해야겠다
- DB 마이그레이션 스크립트를 짠다고 해도, 단계적으로 접근해야할 듯 하다 (위험요소가 많음)
- 읽어야할 책을 또 소개해주다니 참 좋으신 분이다 ^^
#
요약 정리- 정의: 겉보기 동작은 유지한 채, 코드를 이해하고 수정하기 쉽도록 내부 구조를 변경하는 것
- 두 개의 모자 전략으로
기능 추가
,리팩터링
을 동시에하지 않는다 - 리팩터링의 이유: 설계의 질 상승, 장기적 생산성
- 리팩터링 시점: 코드를 이해하기 위해, 기능 추가 시작 전, 기능 추가하다 발견되었을 때 등 다양함
- CI + Test 는 기존의 기능 유지 보장을 위한 체계로 유용 (리팩토링 후 기능 유지 보장)
- 리팩토링 + 자가 테스트 코드 = TDD
#
정리#
2.1 리팩터링 정의- 특정한 방식에 따라 코드를 정리하는 것 (코드를 정리하는 모든 작업이 리팩터링은 아님)
- 리팩터링하기 전과 후의 코드가 똑같이 동작해야 함
- 성능이 변화할 수 있고, 발견하지 못한 버그가 수정될 수 있음
- 리픽터링의 목적은 코드를 이해하고 수정하기 쉽게 만드는 것
#
2.2 두 개의 모자- 기능 추가, 리팩터링 이라는 두개의 모자
- 기능 추가 모자를 쓸 땐, 새 기능을 추가하고 테스트를 통과하는지만 확인
- 리팩터링 모자를 쓸 시, 코드 재구성에만 전념
#
2.3 리팩터링하는 이유리팩터링이 만병 통치약은 아니나, 코드를 건강한 상태로 유지하는데 도와준다
#
소프트웨어 설계가 좋아진다- 지속적인 리팩터링은 코드의 구조를 지탱해줄 것이다
- 중복 코드를 제거하면 모든 코드가 고유한 일을 수행함을 보장할 수 있음
#
소프트웨어를 이해하기 쉬워진다- 리팩터링을 하면 코드의 목적이 더 잘드러나게, 내 의도를 더 명확하게 전달하도록 개선할 수 있음
- 몇 달이 지나 누군가 내 코드를 수정하고자 읽게될 수 있음
- 그 누군가가 보통 본인...
#
버그를 쉽게 찾을 수 있다- 코드를 이해하기 쉽다는 말은 버그를 찾기 쉽다는 말이기도 함
- 켄트 백: 난 뛰어난 프로그래머가 아니에요. 단지 뛰어난 습관을 지니 괜찮은 프로그래머일 뿐이에요.
#
프로그래밍 속도를 높일 수 있다- 앞에 특징들이 따라오면서 프로그래밍 생산성도 자동적으로 높아짐
- 처음부터 좋은 설계를 마련하기란 어려움
- 빠른 개발을 하기 위해서는 리팩터링이 반드시 필요
#
2.4 언제 리팩터링해야 할까?3의 법칙
: 3번째 같은일 반복할 때 리팩터링
#
준비를 위한 리팩터링: 기능을 쉽게 추가하게 만들기- 리팩터링이 가장 좋은 시점은 코드베이스에 기능을 새로 추가하기 직전
- 중복에 대해선 함수 매개변수화 하기 (11.2) 를 적용
- 기능이 한 곳에 모이게 되므로 버그 잡기에도 용이
#
이해를 위한 리팩터링: 코드를 이해하기 쉽게 만들기- 코드를 수정하려면 먼저 그 코드가 하는 일을 파악해야 함
- 그 코드 의도가 더 명확하게 드러나도록 리팩터링할 여지가 없는지 찾아봄
- 함수 이름, 로직 구조 등
- 수정한 코드를 테스트해보면 내 생각이 맞는지 확인 가능
- 내가 이해한걸 코드로 옮겨두면 더 오래 보존할 수 있고, 동료들도 알 수 있음
#
쓰레기 줍기 리팩터링- 코드를 파악하던 중 일을 비효율적으로 처리하는 코드를 발견할 수 있음
- 간단히 수정할 수 있으면 즉시하고
- 시간이 좀 걸린다면 짦은 메모만 남긴 다음, 급한 일 부터 처리 후 시간되면 처리
- 항상 처음 봤을 때 보다 더 깔끔하게 정리하고 떠나자
#
계획된 리팩터링과 수시로 하는 리팩터링보기 싫은 코드를 발견하면 리팩터링하자. 그런데 잘 작성된 코드 역시 수많은 리팩터링을 거쳐야 한다.
- 수시로 하는 리팩터링
- 리팩터링은 프로그래밍과 구분되는 별개의 활동이 아니다
- 새기능을 추가하기 쉽도록 코드를
수정
하는 것이 그 기능을 가장 빠르게 추가하는 길일 수 있다
- 계획된 리팩터링이 무조건 나쁘다는 말은 아님
- 하지만 계획된 리팩터링은 기존에 리팩터링을 하지 않았다는 반증이므로 최소한으로 줄이는 것이 좋음
- 리팩터링 커밋을 분리한다고 무조건적으로 좋은 것은 아님
- 팀에서 적절한 방식을 찾아나가자
무언가 수정하려 할 때는 먼저 수정하기 쉽게 정돈하고 그런 다음 쉽게 수정하자 _켄트백
#
오래 걸리는 리팩터링- 팁 전체가 리팩터링에 매달리는 데는 회의적
추상화로 갈아타기
- 라이브러리를 교체할 때는 기존 것과 새 것 모두를 포용하는 추상 인터페이스부터 마련한다
#
코드리뷰에 리팩터링 활용하기- 기회가 닿는대로 코드리뷰를 하는 편
- 코드리뷰 시 직접 리팩터링해보기
짝 프로그래밍
: 작성자와 나란히 앉아서 코드를 훑어가며 리팩터링하기
#
리팩터링하지 말아야 할 때- 굳이 수정할 필요가 없다면 리팩터링하지 않음
- 처음부터 새로 작성하는게 리팩터링 보다 쉬울 때
#
2.5 리팩터링 시 고려할 문제#
새 기능 개발속도 저하- 새 기능을 구현해넣기 편해지겠다 싶은 리팩터링이라면 주저하지 않고 하는 편
- 개발팀을 이끌고 있다면 코드베이스가 더 건강해지는 것을 추구한다는 사실을 팀원들에게 명확히 밝혀야 함
- 리팩터링의 본질은 경제적인 이유 (바이블이라 해야된다! 라는 느낌이 아님)
#
코드 소유권- 공개 API로 오픈했다면 함수이름 바꾸기(6.5)를 적용하고,
- 기존함수도 유지하되 함수 본문에서 새 함수를 호출하도록 수정
- 코드의 소유권을 팀에두고, 팀원이라면 누구나 수정할 수 있게 관리하는 것이 좋음
#
브랜치- 기능 브랜치 방식의 단점
- 독립 브랜치로 작업하는 기간이 길어질수록 마스터로 통합하기 어려워 짐
- 머지의 복잡도를 줄일 수 있어 CI를 선호하지만, 가장 큰 이유는 리팩터링과 궁합이 좋음
- 그래도 기능별 브랜치를 사용한다면 통합 주기만큼은 최대한 짧게 가져가는게 좋음
#
테스팅- 리팩터링의 두드러진 특성은 프로그램의 겉보기 동작이 똑같이 유지된다는 것
- 리팩터링을 위해서 자가 테스트 코드 (self-testing code) 가 필요함
- 오류를 빨리잡으려면 다양한 측면을 검사하는 test suite 가 필요함
- 리팩터링 과정에서 버그가 생길 위험이 아주 크다는 불안감을 해소할 수 있음
- CI에 통합된 테스트는 XP의 권장사항이자 CD의 핵심
#
레거시 코드- 레거시 코드는 대체로 복잡하고 테스트도 제대로 갖춰지지 않은 것이 많다
- 쉽게 해결할 방법은 없음
레거시 코드 활용 전략
(에이콘, 2018) 을 따라보는걸 추천함- 단번에 리팩터링은 많이 힘드므로, 캠핑 규칙에 따라 당작 작업해야하는 부분부터 단계적으로 해보자
#
데이터베이스- 진화형 데이터베이스 설계, 데이터베이스 리팩터링
- 핵심
- 마이그레이션 스크립트 작성
- 접근 코드와 DB 스키마에 대한 구조적 변경을 해당 스크립트로 처리하게끔 통합
- 단계 (병렬 수정, 팽창-수축 의 일반적 예)
- 첫 커밋은 필드 추가만
- 후에 기존 필드와 새필드를 동시에 업데이트하도록 설정
- DB를 읽는 클라이언트들을 새 필드를 사용하는 버전으로 점진적 업데이트
- 모두 교체 작업을 마무리하였으면 예전 필드는 삭제
- 핵심
#
2.6 리팩터링, 아키텍처, 애그니(YAGNI)- 리팩터링이 아키텍처에 미치는 실전적 효과
- 요구사항 변화에 자연스럽게 대응하도록 코드베이스를 잘 설계해준다
- 리팩터링은 현재까지 파악한 요구사항만을 해결하는 소프트웨어를 구축
- 이런식의 설계를 아래와 같이 부름
- 간결한 설계 (simple design)
- 점진적 설계 (incremental design)
- YAGNI (애그니, you aren't going to need it, 필요 없을 것임)
#
2.7 리팩터링과 소프트웨어 개발 프로세스- 팀의 실천법에 따라 리팩터링의 효과가 크게 달라짐
테스트 주도개발
은 자가 테스트 코드와 리팩터링을 묶는 말- 애자일을 제대로 적용하려면 리팩터링에 대한 팀의 역량과 열정이 뒷밤침 되어 프로세스 전반에 리팩터링이 자연스럽게 스며들도록 해야함
- 리팩터링의 토대: 테스트코드
- 자가 테스트 코드, 지속적 통합, 리팩터링이라는 세 기법은 서로 강력한 상승효과를 불러 일으킴
#
2.8 리팩터링과 성능- 직관적 vs 성능
- 리팩터링하면 소프트웨어가 느려줄 수 있다는 건 팩트
- 하지만 성능 튜닝하기엔 쉬워짐
- 빠른 소프트웨어를 작성하는 방법 세 가지
- 시간 예산 분배: 컴포넌트 별로 시간 limit을 할당
- 끊임없는 관심
- 성능 최적화 전 코드를 다루기 쉽게 만드는데 집중 (이땐 성능 신경 X)
- 리팩터링을 잘해두면 최적화의 두가지면에 도움됨
- 성능 튜닝에 투입할 시간 벌기
- 성능을 더 세밀하게 분석 가능
2.9는 스토리므로 생략
#
2.10 리팩터링 자동화- IDE에서 리팩터링 자동화를 지원해줌 -> 이를 적극 활용하자
#
2.11 더 알고 싶다면- 리팩터링 연습은 윌리엄 웨이크가 쓴
리팩터링 워크북
을 추천 - 패턴을 활용한 리팩터링 _조슈아 케리에프스키
- 레거시 코드 활용전략 _마이클 페더스