본문 바로가기

Untagged

리팩터링 2판 요약 - 챕터 2

728x90
728x90

2.1 리팩터링 정의

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

 

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

 

겉보기 동작(Observable Behavior): 리팩터링 전과 후의 코드가 완벽히 똑같이 작동해야 함. 성능의 차이가 발생하고 같은 결과를 보여주기만 하면 됨.

2.2 두 개의 모자(Two hats)

Two hats는 일인이역을 뜻함.

 

소프트웨어 개발의 목적을 "기능 추가", "리팩터링"으로 구분함.

 

소프트웨어를 개발할 때는 기능 추가 모자와 리팩터링 모자 두 개를 자주 바꾸면서 개발함. 본인이 어떤 모자를 썼는지 인지할 필요가 있음.

2.3 리팩터링하는 이유

소프트웨어의 설계가 좋아짐

소프트웨어를 이해하기 쉬워짐

버그를 찾기 쉬움

프로그래밍 속도를 높일 수 있음

2.4 언제 리팩터링해야 할까?

Rule of Three: 처음에는 그냥 한다. 비슷한 일을 두 번째로 하게 되면 일단 한다. 세 번째 하게 되면 리팩터링 한다.

준비를 위한 리팩터링: 기능을 쉽게 추가하게 만들기

코드베이스에 기능을 추가하기 직전 한다.

이해를 위한 리팩터링: 코드를 이해하기 쉽게 만들기

코드를 수정하기 전 리팩터링을 하면 코드가 무슨 일을 하는지와 그 설계를 이해할 수 있다.

쓰레기 줍기 리팩터링

캠핑 규칙: 캠핑장에서 나올 때는 들어갈 때보다 더 깨끗하게 해야 한다.

 

코드를 파악하면서 쓸데없이 복잡하거나 이상한 부분이 있으면 고치는 게 좋다. 간단한 건 바로 고치고, 오래 걸리는 수정 사항은 원래 하려던 일을 끝내고 한다.

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

앞선 리팩터링은 모두 기회가 있을 때 하는(opportunistic) 리팩터링.

 

리팩터링은 별도의 작업이 아니라 개발을 하면서 병행하는 것.

 

다만 계획된 리팩터링이 무조건 나쁘다는 것은 아님. 그동안 리팩터링에 소홀했으면 따로 시간을 낼 필요가 있음. 다만 그 시간은 최소화할 것.

오래 걸리는 리팩터링

리팩터링은 대부분 몇 분 안에 끝나며 길어야 몇 시간 정도 걸림.

 

하지만 라이브러리 교체와 같이 팀 전체가 몇 주 동안 해야 하는 리팩터링이 있음.

 

팀 전체가 리팩터링에 매달리기 보다는 관련 코드를 만날 때 하는 식으로 몇 주에 걸쳐서 하는 게 좋다.

코드 리뷰에 활용하기

리팩터링은 다른 이의 코드를 리뷰하거나 코드 리뷰의 결과를 구체적으로 도출하는데 도움이 됨.

관계자에겐 뭐라고 말해야 할까?

매니저가 리팩터링이 뭔지 모르면 그냥 말하지 말 것. 개발 일정에 따라 잘 판단해서 리팩터링 수행

리팩터링 하지 말아야 할 때

지저분한 코드를 발견해도 굳이 수정할 필요가 없으면 냅둠

 

리팩터링보다 새로 짜는 게 빠를 경우

2.5 리팩터링 시 고려할 문제

리팩터링은 중요하지만 딸려 오는 문제가 있기에, 이에 대해 알아둘 필요가 있음.

새 기능 개발 속도 저하

리팩터링이 당장의 속도 저하를 일으키는 것처럼 보일 수 있음. 하지만 지속적인 코드베이스 개선을 통해 생산성을 키우도록 해야 한다.

코드 소유권

어떤 코드가 다른 팀한테 관리되고 있거나 API 그 자체일 경우 제약이 있지만 리팩터링 가능.

 

되도록 코드의 소유권이 세밀해서는 안된다.

브랜치

개별 기능 브랜치의 작업 기간이 길어질수록 메인 브랜치에 통합(기능 브랜치에서 메인으로 머지하는 것) 하기 어려워짐.

 

지속적 통합(Continuous Integration) 또는 트렁크 기반 개발(Trunk-Based Development)을 통해 기능 브랜치의 통합 주기를 2~3일 단위로 짧게 관리해야 함.

 

CI를 완전히 적용하진 못하도 브랜치의 주기를 최대한으로 짧게 하도록 하자.

테스팅

리팩터링 후에도 동작은 같아야 하지만 실수를 하는 경우가 있음. 실수를 빨리 해결하면 괜찮음.

 

핵심은 오류를 빨리 잡아야 하고 이를 위해선 test suite가 필요. 즉, 리팩터링을 위해서 self-testing 코드가 필요함.

 

테스트 코드는 기능 추가를 안전하게, 그리고 리팩터링을 할 수 있게 해 줌(버그 발생에 대한 불안감 해소).

 

테스트를 하지 않고 툴에서 제공하는 자동 리팩터링을 사용해도 좋음.

 

링크에서 대규모 코드베이스에 효과적인 리팩터링 방식을 볼 수 있음.

레거시 코드

레거시 코드는 대체로 복잡하고 테스트도 없는 경우가 많음.

 

레거시 시스템을 파악할 때 리팩터링이 큰 도움을 주지만 테스트 코드 없이 명료하게 하기엔 힘듦.

 

일단 테스트를 갖출 것이 권장되지만 레거시 코드가 테스트를 고려하지 않은 경우 상당히 까다로움.

 

이에 대한 조언은 레거시 코드 활용 전략을 참조할 것.

데이터베이스

데이터베이스에서의 리팩터링은 expand-contract를 따름. 한 번에 리팩터링을 끝내는 게 아니라 여러 릴리스에 걸쳐서 하는데, 예를 들어 컬럼의 이름이 바뀌면 옛날 이름의 컬럼은 일단 내버려두고 새 이름의 동일한 역할을 하는 컬럼을 추가함(팽창). 그렇게 점차 이주를 하면서 옛날 컬럼을 제거(수축)

2.6 리팩터링, 아키텍처, YAGNI

You Aren't Going to Need It(YAGNI): 그럴 필요 없다의 뜻으로, 미래의 설계를 미리 반영할 필요가 없다는 의미로 쓰인다.

 

실제로 개발할 때는 요구 사항이 바뀌므로 미래에 있을 일을 생각해 과도한 설계를 할 필요가 없다.

 

리팩터링이라는 개념이 자리 잡은 지금은 필요한 기능 추가에 중점을 두고, 나중에 리팩터링을 통해 구조를 개선하도록 한다.

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

XP(eXtreme Programming): 최초의 애자일 개발론

 

애자일을 제대로 이행하려면 리팩터링에 대한 팀의 역량과 열정을 기반으로 프로세스 전반에 리팩터링이 스며들어야 함.

 

팀으로 개발하면서 리팩터링 하려면 각 팀원이 다른 사람의 작업을 방해하지 않아야 하고 이는 CI를 해야 할 이유가 됨.

 

테스트 코드, 리팩터링, self-testing code가 잘 이행되면 YAGNI 개발이 가능하며 아이디어를 프로덕션에 반영하는 시간도 단축하고 버그도 줄여줄 수 있음.

 

말은 쉽지만 실무는 복잡하기에 충분한 연습과 실력이 있어야 함.

2.8 리팩터링과 성능

아무것도 안 만드는 데도 시간이 걸린다.

어떤 시스템이 너무 느려져서 팀원과의 긴 토론을 통해 A가 문제라 추정했는데 프로파일러로 모니터링하니 사실은 B였다는 일화.

 

대부분의 프로그램은 극히 일부에서 대부분의 시간을 사용한다. 그러므로 최적화를 위한 시간을 할당할 경우 외에는 코드를 다루기 쉽게 만드는데 집중하고 성능 최적화 단계에서 튜닝하도록 하자.

 

리팩터링을 하는 그 순간에는 성능이 느려질 수 있지만 코드가 성능 튜닝을 하기 좋게 변하기 때문에 결국은 개선을 쉽게 할 수 있음.

2.9 리팩터링의 유래

저자는 1980년 스몰토크라는 것을 활용해서 개발했는데 당시 리팩터링을 활용하기에 좋았음.

 

GoF 중 한 명인 랄프 존슨의 박사 과정생인 빌 옵다이크가 리팩터링에 대한 논문을 최초로 발표함.

2.10 리팩터링 자동화

요즘은 자동 리팩터링을 해주는 도구가 많아짐(*참고: 해당 책의 1판은 1999년에 나옴)

 

자동 리팩터링을 제대로 하려면 코드를 syntax tree로 다뤄야 함.

 

최근에는 Language Server라는 기술로 API를 통해 텍스트 에디터에서도 리팩터링을 이용할 수 있음

2.11 더 보기

리팩터링 연습에 집중하고 싶으면 리팩터링 워크북을 본다.

 

디자인 패턴과 어우러져 리팩터링 하는 방법은 패턴을 활용한 리팩터링을 본다.

 

분야에 특화된 리팩터링 방법은 리팩토링 데이터베이스, 리팩토링 HTML이 있다.(*둘 다 오래돼서 지금 봐도 되는지는 모르겠다.)

 

최신 자료는 https://refactoring.com을  참조한다.

728x90
728x90

'Untagged' 카테고리의 다른 글

PS 노베이스의 ICPC 도전 가이드  (1) 2024.01.01
리팩터링 2판 요약 - 챕터 6  (1) 2023.12.17
리팩터링 2판 요약 - 챕터 3  (0) 2023.12.03
[numpy] unravel_index  (0) 2022.01.02