리팩터링 정리 _ Chapter02

김수근·2022년 8월 19일
0

코드를 작성하면서 내가 잘 작성하고 있는가라는 생각이 들 때가 많았습니다.
리팩터링이라는 책을 읽으면서 추측으로만 생각했던 것들이나 알지 못했던 부분들을 알게 되는 것 같아서 읽은 내용들을 바탕으로 정리를 했습니다.

리팩터링 정의

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

리팩터링하다[동사] : 소프트웨어의 겉보기 동작은 그대로 유지한 채, 여러가지 리팩터링 기법을 적용하여 소프트웨어를 재구성 한다.



리팩터링을 하는 이유

  • 소프트웨어 설계가 좋아집니다.
    • 나쁜 설계로 인해서 코드가 길어진 부분들을 리팩터링을 하게되면서 코드의 중복제거와 고유한 일의 수행을 보장하는 코드로 변경됩니다.
  • 코드의 목적이 잘 드러나게, 의도를 명확하게 전달할 수 있도록 개선이 되기 때문에 소프트웨어를 이해하기 쉬워집니다.
  • 버그를 쉽게 찾을 수 있습니다.
    • 리팩터링을 진행하면서 코드가 하는 일을 깊이 파악하게 되고 구조를 명확하게 다듬으면 문제점이 명확하게 드러납니다.
  • 프로그래밍 속도를 높일 수 있습니다.
    • 기존의 코드를 리팩터링하면 오히려 시간을 할당해야되서 더 걸린다는 생각을 가질 수 있지만, 나쁜 설계 부분을 좋은 설계로 바꾸게 되면서 장기적인 기능누적으로 봤을 때는 시간이 감소하는 모습을 보입니다.



언제 리팩터링을 해야 하나?

3의 법칙
1. 처음에는 그냥한다
2. 비슷한일을 두번째로 하게 되면 일단은 계속한다.
3. 비슷한 일을 세 번째 하게 되면 리팩터링한다.

준비를 위한 리팩터링

기능을 추가하기 직전 코드를 살펴보면서 구조를 바꾸면 다른 작업을 하기가 쉬워질 만한 부분을 찾는다. 요구 사항을 모두 만족하지만 매개변수나 리터럴 값 몇개로 인해 다른 비슷한 함수를 만들어야 될 때가 있는데 이런 부분들을 나중을 위해서 리팩터링을 진행하는 경우

이해를 위한 리팩터링

코드를 수정하기 위해서는 코드를 이해하는것에서 부터 시작된다. 이런 이해를 쉽게 하기 위해 코드의 의도가 더 명확하게, 함수의 이름은 잘못 지정되지 않았는지 수정. 시간이 지나면 잊게 되기 때문에 코드 자체를 이해하기 쉽게 리팩토링 해놓는것이 나중에 도움이 된다.

쓰레기줍기 리팩터링

간단히 수정할 수 있는 것은 즉시 고치고, 시간이 걸리는 일은 짧은 메모만 남긴 다음 시간이 날 때 마다 수정한다. 처음 코드를 봤을 때 보다 깔끔하게 정리하고 떠나자. 대신 리팩토링을 진행 할 때 코드의 기능이 깨지면 안된다.( 기존 기능을 변경하라는 의미는 아니라고 해석함 )

계획&수시로 하는 리팩터링

일정을 미리 잡아둔 계획적 그리고 수시로 코드를 수정해 나가는 리팩터링이다. 무언가 수정하려 할 때는 먼저 수정하기 쉽게 정돈하고 그런다음 쉽게 수정하자.

오래 걸리는 리팩터링

팀 전체가 리팩터링에 매달려 하는것이 아니라 주어진 문제를 몇 주에 걸쳐 조금씩 해결하는 편이 효과적이다.

코드리뷰에서 리팩터링

리팩터링을 통해서 다른 사람의 코드를 리뷰하는데에 도움이 된다. 코드 리뷰의 결과를 더 구체적으로 도출하는데 도움이 된다. 작성자와 나란히 앉아서 코드를 훑어가면서 리팩터링하면 자연스럽게 짝 프로그래밍이 된다.



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

지저분한 코드를 발견하더라도 굳이 필요가 없다면 리팩터링 하지 않는다. 외부 API다루듯 호출해서 쓰는 코드라면 그냥 둔다. 내부 동작을 이해해야 할 시점에 리팩터링 해야 효과를 볼 수 있다.
리팩터링보다 처음부터 새로 작성하는 게 쉬울 때도 리팩터링하지 않는다. 이런 상황을 판단하긴 쉽지 않아 결정하려면 경험과 뛰어난 판단력이 뒷받침 되야 한다.



리팩터링시 고려할 문제

새 기능 개발 속도 저하

리팩터링으로 인해 진행이 느려진다고 생각하는 사람들이 많은데 적은 노력으로 더 많은 가치를 창출하는 것이 리팩터링의 목적이다. 가장 위험한 오류는 리팩터링을 클린코드나 바람직한 엔지니어링 습관처럼 도덕적인 이유로 정당화 하는 것이다. 리팩터링은 오로지 경제적인 이유로 하는것이며 개발 기간을 단축하고 기능 추가 시간을 줄이고 버그 수정 시간을 줄여준다.

코드 소유권

기존 함수도 그대로 유지하되 함수 본문에서 새함수를 호출하도록 수정한다. 코드의 소유권을 작은단위로 나누지 말고 팀에 두어 누구나 팀이 소유한 코드를 수정할 수 있게 한다.

Branch

독립 브랜치로 작업하는 기간이 길어질수록 작업 결과를 마스터로 통합하기가 어려워진다. 고통을 줄이고자 많은 이들이 마스터를 개인 브랜치로 수시로 rebase하거나 merge한다. 기능별 브랜치의 통합주기를 2~3일 단위로 짧게 관리해야한다. 마스터를 건강하게 유지하고 거대한 기능을 잘게 쪼개는 법을 배우고, 각 기능을 끌 수 있는 기능 토글을 적용하여 완료되지 않은 기능이 시스템 전체를 망치지 않도록 해야한다.

테스팅

리팩터링을 하기 위해서는 대부분의 경우에 자가 테스트 코드를 마련해야 한다. 테스트 코드를 갖추면서 프로그래밍하기는 쉽지 않지만 자가 테스트 코드는 리팩터링을 할 수 있게 해줄 뿐만아니라, 새 기능 추가도 훨씬 안전하게 진행할 수 있도록 도와준다.

레거시 코드

레거시 시스템을 파악하는데 리팩터링이 도움이 된다. 레거시 코드 활용 전략에서 프로그램에서 테스트를 추가할 틈새를 찾아서 시스템을 테스트 해야한다고 나와있다. 테스트를 갖추고 있더라도 복잡하게 얽힌 레거시 코드를 아름다운 코드로 단번에 리팩터링하는 데는 낙관적이지 않다. 서로 관련된 부분끼리 나눠서 하나씩 공략하고 코드의 한부분을 훑고 넘어갈 때마다 예전보다 조금이라도 개선하려고 노력한다.

데이터 베이스

진화형 데이터베이스 설계 기법은 커다란 변경들을 쉽게 조합하고 다룰 수 있는 데이터 마이그레이션 스크립트를 작성하고, 접근코드와 데이터베이스 스키마에 대한 구조적 변경을 이 스크립트로 처리하게끔 통합하는 것이다. 이 기법도 작고 독립된 단계들로 쪼개는 것이 핵심이다. 데이터 베이스 리팩터링은 프로덕션 환경에 여러 단계로 나눠서 릴리스하는 것이 대체로 좋다는 점에서 다른 리팩터링과 다르다.



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

현재까지 파악한 요구한 사항만을 해결하는 소프트웨어를 구축하고 설계한다. 진행하면서 이용자의 요구사항을 더 잘 이해하게 되면 아키텍처도 그에 맞게 리팩터링해서 바꾼다. 이런 설계 과정을 간결한 설계, 점진적 설계, YAGNI(you aren't going to need it)등으로 부른다.



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

자가 테스트 코드와 리팩터링을 묶어서 테스트 주도 개발(TDD : test driven development)라고 한다.



리팩터링과 성능

리팩터링을 하면서 성능이 느려질 수는 있지만 그와 동시에 성능을 튜닝하기는 더 쉬워진다. 튜닝을 쉽게 하게 만들고 나서 원하는 속도가 나오게끔 튜닝한다.

profile
✏️ 꾸준하게 기록하자

0개의 댓글