리팩토링
리팩토링을 더 이상 두루뭉실한 의미로 사용하지 말자.
리팩토링은 명사, 동사로 쓸 수 있다.
- 명사 : 소프트웨어의 겉보기 동작은 그대로 유지한채, 코드를 이해하고 수정하기 쉽도록 내부 구조를 변경하는 기법
- 동사 : 소프트웨어의 겉보기 동작은 그대로 유지한채, 여러 가지 리팩토링 기법을 적용해서 소프트웨어를 재구성한다.
코드를 정리하는 작업은 리팩토링이 아니다.
리팩토링은 동작을 보존하는 작은 단계들을 거쳐 코드를 수정하고, 이러한 단계를 순차적으로 연결하여 큰 변화를 만들어 내는 일이다.
리팩토링은 그 자체로 아주 작을 수도 있고 작은 단계 여러 개가 합쳐진 모습 일 수도 있다.
리팩토링 하는 동안 코드가 항상 정상 작동하기 때문에 전체작업이 끝나지 않았더라도 언제든지 멈출 수 있다. 그러므로 누군가 리팩토링 하다가 코드가 깨져서 몇 일을 고생 했다면, 십중팔구 리팩토링 하는 것이 아니다.
재구성(restructin)
- 코드베이스 정리
- 구조를 바꾸는 모든 작업
- 포괄적인 의미로 쓰인다
리팩토링(refactoring)
- 재구성 중 특수한 형태
잘게 일을 나누어 작업하는 것은 비효율이 아닌, 효율적인 작업 방법이다. 디버깅 시간이 엄청 줄어들 것이다.
리팩토링은 사용자 관점에서 변화는 없지만 성능과 코드 품질에 변화를 준다.
리팩토링은 성능 최적화와 비슷하다. 둘다 코드를 변경하지만 전반적인 기능은 그대로 유지한다. 리팩토링은 프로그램의 성능이 좋아질 수도 나빠질 수도 있다. 반면에 성능 최적화는 오로지 속도에만 신경쓴다.
기능 개발과 리팩토링이라는 두 개의 모자
기능 개발과 리팩토링은 모자이다. 한 번에 두개 쓸 생각하지마라.
기능 추가 할 때는 기존 코드는 절대 건드리지 않는다. 새 기능만 추가한다. 리팩토링 할 때는 기능 추가를 절대 하지 않기로 다짐한 뒤 오로지 코드 재구성에만 전념한다. 그렇다고 모자를 바꿔쓰지 말라는 것은 아니다. 하나의 기능 추가나 리팩토링이 끝나면 모자를 바꿔 쓸지는 작업 효율성에 따라 선택하면 된다.
리팩토링을 하는 이유
리팩토링은 소프트웨어의 모든 문제점을 해결하는 만병통치약이 절대 아니다. 하지만 코드를 건강한 상태로 유지하는 데 도움을 주는 약임은 분명하다. ( 건강이 한 번 나빠지면 되돌리기란 쉽지 않다. 코드의 건강도 그러하여 이렇게 밥 선생님께서는 말한다. )
리팩토링은 다양한 용도로 활동 할 수 있고, 또 반드시 그래야 하는 도구다.
리팩토링하면 소프트웨어 설계가 좋아진다.
리팩토링 하지 않는 소프트웨어는 아키텍처를 충분히 이해하지 못 한채 단기 목표만을 위해 코드를 수정하다 보면 기반구조가 무너지기 쉽다. 코드만 봐서는 설계를 파악하기 어려워진다. 코드구조가 무너지면 악효과가 누적된다. 코드만으로 설계 파악하기 어려워질 수록 설계를 유지하기 어려워지고 설계가 부패되는 속도가 더욱 빨리진다.
중복을 줄이고 코드량을 줄이면 수정하는 데 드는 노력은 크게 줄어든다.
리팩토링하면 소프트웨어를 이해하기 쉬워진다.
프로그래밍은 여러 면에서 마치 컴퓨터와 대화는 것과 같다. 컴퓨터에게 시킬 일을 표현하는 코드를 작성하면, 컴퓨터는 정확하게 시킨대로 반응한다. 컴퓨터에게 시키려는 일과 이를 표현한 코드의 차이를 최대한 줄여야 한다. 프로그래밍은 결국 내가 원하는 바를 정확하게 표현하는 일이다.
프로그래밍에서는 사람이 가장 중요하지만 소홀하기 쉽다. 다른 프로그래머가 내 코드를 제대로 이해했다면 1시간에 끝낼 수정을 인주일이나 걸린다면 사정이 달라진다. 문제는 프로그램을 동작시키는 데만 신경쓰다 보니, 나중에 그 코드를 다룰 개발자를 배려하지 못 하는 데 있다.
코드를 이해하기 쉽게 만드려면, 일하는 리듬에 변화를 줘야 한다.
리팩토링은 코드가 더 잘 읽히게 도와준다. 작동하지만 이상적인 구조가 아닌 코드가 있다면 잠깐 시간 내어 리팩토링해보자. 그러면 코드의 목적이 더 잘 드러나게 되어 내 의도 또한 명확하게 전달하도록 개선 할 수 있다.
리팩토링하면 버그를 쉽게 찾을 수 있다.
- 켄트 백 : 난 뛰어난 프로그래머가 아니에요. 단지 뛰어난 습관을 지닌 괜찮은 프로그래머 일 뿐이에요. ( 아... 난 뭐냐. 이래서 난 괜찮은 프로그래머라고 말 못 한다. )
리팩토링하면 프로그래밍 속도를 높일 수 있다. 서비스의 복잡도가 올라갈수록 더더욱 그렇다.
내 코드가 고대 유물처럼 이해하기 어렵지 않기를...
내부 설계가 잘 된 소프트웨어는 새로운 기능을 추가할 지점과 어떻게 고칠 지 쉽게 찾을 수 있다.
내부 설계에 심혈을 기울이면 소프트웨어의 지구력이 높아져서 빠르게 개발 할 수 있는 상태를 오래 지속 할 수 있다.
빠른 개발이라는 숭고한 목표를 달성하려면 리팩토링이 반드시 필요하다.
언제 리팩토링 해야 할까?
한 시간 간격으로 리팩토링 한다.
돈 로버츠의 제시
- 처음에는 그냥 한다.
- 비슷한 일을 두번째로 하게 되더라도 일단 계속한다. ( 중복이 생겼다는 사실에 충격과 공포를 느끼면서 )
- 비슷한 일을 세번째 하게 되면 리팩토링 한다.
스트라이크 세번이면 리팩토링 한다.
준비를 위한 리팩토링 - 기능 추가 직전, 기능 추가를 쉽게 하기 위한 준비
기능 추가 직전에 하는 이 리팩토링하기 가장 좋은 시점이다.
코드베이스에 기능을 새로 추가하기 직전 구조를 살짝 바꾸면 더 작업하기 수월해진다. 이러한 부분을 찾아보자.
비유하면 지금 위치에서 동쪽으로 100KM를 이동하려는 데, 그 사이를 숲이 가로막고 있다면 좀 둘러가더라도 북쪽에 있는 고속도로를 타는 편이 세 배나 빠를 수 있다. 다들 직진을 외치더라도, 때로는 "잠깐, 지도를 보고 가장 빠른 경로를 찾아보자"고 말할 줄 알아야 한다.
이해하기 위한 리팩토링 - 코드를 이해하기 쉽게 만들기
코드를 수정하려면, 먼저 그 코드가 하는 일을 파악해야 한다. 그 코드를 작성한 사람은 자신 일 수도 있고 다른 사람 일 수도 있다.
코드를 파악 할 때 마다 그 코드의 의도가 더 명확하게 드러나도록 리팩토링 할 여지는 없는 지 찾아보자.
- 조건부 로직의 구조
- 함수 이름의 명확성
- etc
어떤 역할을 하는 지 이해 된 변수는 적절한 이름으로 바꿔주고, 긴 함수는 잘게 나누기도 한다.
랄프 존스 - 초기 단계의 리팩토링은 밖을 잘 내다보기 위한 창문 닦기에 비유한다.
코드를 분석 할 때 리팩토링을 해보면, 그렇지 않았다면 도달하지 못 했을 더 깊은 수준까지 이해하게 된다.
쓰레기 줍기 리팩토링
일을 비효율적으로 처리한 코드
- 로직이 쓸데없이 복잡
- 매개변수화한 함수 하나면 될 일을 똑같은 여러 함수로 작성
이때는 절충안이 필요하다. 원래 하던 일 외에 많은 시간을 뺏기긴 싫을 것이다. 그렇다고 쓰레기를 방치하는 것도 좋지 않다.
마틴의 선택 - 간단히 수정 할 수 있는 것은 즉시 고치고 시간이 좀 걸리는 일은 짧은 메모만 남긴 다음 하던 일을 끝내고 처리한다.
캠핑 규칙을 떠올려라
리팩토링의 멋있는 점은 각각의 작은 단계가 코드를 깨뜨리지 않는 다는 사실이다.
계획 된 리팩토링과 수시로 하는 리팩토링
- 준비를 위한 리팩토링
- 이해를 위한 리팩토링
- 쓰레기 줍기 리팩토링
위 3가지는 기회가 될 때만 진행한다.
마틴은 개발에 들어가기 전에 리팩토링 일정을 따로 잡아두지 않고 기능을 추가하거나 버그를 잡는 동안 리팩토링도 함께 한다. 프로그래밍 과정에 자연스럽게 녹인 것이다.
기능을 추가할 때든 버그를 잡을 때든 리팩토링은 눈앞의 문제점 뿐만 아니라 앞으로 작업에 도움을 준다.
리팩토링은 프로그래밍과 구분되는 별개의 활동이 아니다.
보기 싫은 코드를 발견하면 리팩토링하자.
그런데 잘 작성 된 코드 역시 수 많은 리팩토링을 거쳐야 한다. 리팩토링은 과거에 저지른 실수를 바로 잡거나 보기 싫은 코드를 정리하는 작업이라고 오해하기 쉽다. 잘 작성된 코드 역시도 수 많은 리팩토링을 거쳐야 한다.
무언가 수정하려 할 때는 먼저 수정하기 쉽게 정돈하고 그런 다음 쉽게 수정한다. ( 이 작업이 쉽다는 것은 아니다. )
뛰어난 개발자는 새기능을 추가하기 쉽도록 코드를 '수정'하는 것이 그 기능을 가장 빠르게 추가할 수 있음을 안다.
소프트웨어 개발은 끝이 있는 작업으로 보면 안 된다. - ( 큰 일이네 )
게획 된 리팩토링이 무조건 나쁘다는 것은 아니다. 그 동안 리팩토링에 소홀했다면 따로 시간을 내서 새기능을 추가히기 쉽도록 코드베이스를 개선 할 필요가 있다.
정기적으로 리팩토링을 하더라도 어떤 문제는 팀원 여럿이 달려들어야 할 정도로 곪았을 수도 있다. 하지만 이런 이유로 계획 된 리팩토링을 하게 되는 일은 최소한으로 줄여야 한다.
리팩토링 작업 대부분은 드러나지 않게 기회가 될 때 마다 해야한다.
오래 걸리는 리팩토링
대부분의 리팩토링은 몇 분 안에 끝난다. 하지만 팀 전체가 달려들어도 몇 주는 걸리는 대규모 리팩토링도 있다.
- 라이브러리를 새 것으로 교체
- 일부 코드를 라이브러리화 시켜 공유
- 골치 아픈 의존성 정리 작업
마틴은 팀 전체가 리팩토링에 매달리는 것에 회의적이다. 그 보다는 주어진 문제를 몇 주에 걸쳐 조금씩 해결해 가는 편이 효과적일 때가 많다.
추상 인터페이스 ( 너 없으면 못 살아 )
코드 리뷰에 리팩토링 활용하기
코드리뷰로 경험 많은 개발자의 노하우를 더 적은 개발자에게 전수 할 수 있다.
코드리뷰는 깔끔한 코드를 작성하는 데에도 광장히 중요하다.
리팩토링은 다른 이의 코드를 리뷰하는 데도 도움이 된다.
코드 리뷰에 리팩토링을 접목하는 구체적인 방법은 리뷰의 성격에 따라 다르다. 흔히 쓰는 풀리퀘스트 모델에서는 코드리뷰가 그리 효과적이지 않다. 코드 작성자가 참석해야 맥락을 설명해줄 수 있고 작성자도 리뷰어의 변경의도를 제대로 이해 할 수 있 있으므로 이왕이면 작성자가 참석하는 방식이 좋다.
관리자에게 뭐라고 말해야 할까?
리팩토링의 가치를 아는 관리자에게는 말해라. 그렇지 않다면 말하지 말자!
프로 개발자에게 주어진 임무는 새로운 기능을 빠르게 구현하는 것이고, 가장 빠른 방법은 리팩토링이다.
리팩토링하지 말아야 할 때
리팩토링하면 안 되는 상황도 있다.
- 외부 API 다루듯 호출해서 쓰는 코드라면 지저분해도 그냥 둔다.
- 리팩토링하는 것 보다 처음부터 새로 작성하는 게 쉬울 때도 리팩토링하지 않는다.
직접 리팩토링해보기 전에는 쉬운지 확실히 알 수 없을 때도 많기 때문에 이는 뛰어난 판단력과 경험이 뒷받침 되어야 한다.
리팩토링 2판 - 마틴 파울러
또 읽고 또 읽어라.
완전히 외워질때 까지!
그리고 연습해라!
'Level Up > Refactoring' 카테고리의 다른 글
리팩토링 - 소프트웨어 개발 프로세스 (0) | 2020.09.04 |
---|---|
리팩토링 - 리팩터링, 아키텍처, 애그니(YAGNI) (0) | 2020.09.04 |
리팩토링 - 고려할 문제 (0) | 2020.09.04 |
리팩토링 - 기초 단계, 단계와 분리, 다형성 (0) | 2020.09.02 |
리팩토링 - 개요 (1) | 2020.08.31 |