////
Search
5️⃣

5장. 보람 있는 리팩터링

이 장에서 다룰 내용

리팩터링에 익숙해지기
큰 변화를 위해 점진적으로 리팩터링하기
코드를 더 빠르게 변경하기 위해 테스트 사용하기
종속성 주입하기

1. 우리는 왜 리팩터링을 하는가?

리팩터링으로 얻을 수 있는 것은 다음과 같다.
반복을 줄이고 코드 재사용을 증가시킨다
다른 구성 요소에서 재사용할 수 있는 클래스를 공통 위치로 이동시켜 다른 구성 요소에서도 사용할 수 있도록 한다.
마찬가지로 코드에서 메서드를 추출하여 이것을 재사용할 수 있다.
여러분의 정신 모델과 코드를 더 가깝게 한다
이름이 중요하다. 어떤 이름은 쉽게 이해되지 않을 수도 있다. 객체 이름을 바꾸는 것은 리팩터링 과정의 일부이며, 여러분의 정신 모델과 더 잘 맞고 더 나은 설계를 달성하는 데 도움이 될 수 있다.
코드를 더 이해하기 쉽고 유지관리하기 쉽도록 만든다
긴 함수를 더 작고 유지관리하기 쉬운 함수로 분할하여 코드의 복잡성을 줄일 수 있다.
마찬가지로 복잡한 데이터 타입을 더 작은 부분으로 그룹화한다면 모델을 더 쉽게 이해할 수 있다.
특정 클래스에 버그가 발생하지 않도록 한다
클래스를 구조체로 변경하는 것과 같은 특정 리팩터링 작업은 2장에서 다룬 것처럼 널과 관련된 버그를 방지할 수 있다.
마찬가지로 프로젝트에서 널이 가능한 nullable 참조를 활성화하고, 데이터 타입을 널이 불가능한 참조로 변경하면 기본적으로 연산을 리팩터링하는 버그를 방지할 수 있다.
중요한 아키텍처 변화를 준비할 수 있다
변화를 위한 코드를 미리 준비한다면 코드가 크게 변경되더라도 더 빨리 일을 실행할 수 있다.
다음 절에서 이러한 문제가 어떻게 발생할 수 있는지를 알아볼 것이다.
코드의 경직된 부분을 없앨 수 있다
종속성 주입을 통해 종속성을 제거하고 느슨하게 결합된 설계를 얻을 수 있다.
대부분의 리팩토링은 어떠한 지침도 필요없으나 코드 베이스에서 중요한 아키텍처를 변경해야하는 경우, 몇 가지 조언을 따르면 좋다.

2. 아키텍처 변경

한 번에 큰 아키텍처를 변경하는 것은 좋은 생각이 아닌데, 큰 변화는 수많은 버그와 통합적인 문제를 발생시키기 때문이다.
여기서 통합 문제란 대규모 변경 작업이 수행되는 동안, 다른 작업자들과 병렬로 작업을 수행하지 못하는 것을 의미한다.
이러한 이유로 리팩터링은 점진적으로 수행하는 것이 좋다.

1. 구성 요소를 식별하라

대규모 리팩터링을 하는 가장 좋은 방법은 코드를 의미론적으로 다른 구성 요소로 나누는 것이다.

2. 작업량과 위험도를 측정하라

효율적인 리팩터링을 위해서는 작업량과 리스크를 평가하고 우선순위를 지정하는 것이 중요하다.
이를 위해 목표를 명확히 설정하고 프레임워크의 작동 방식을 이해하는 것이 필요하다.
작업 중 일부는 예상과 다를 수 있지만, 목표는 가능한 한 오랜 시간 동안 기존 기능을 유지하면서 필요한 작업을 단계적으로 진행하는 것이다.

3. 평판

리팩터링을 동료를 방해하지 않고 효과적으로 수행하려면 점진적이고 체계적인 접근이 중요하다.
이는 대규모 시스템에서 중요한 부분을 교체하면서도 기존 시스템이 계속 정상적으로 작동하도록 하는 과정과 유사하다

4. 더 쉽게 리팩터링되도록 리팩터링하라

대부분의 경우, 구체적인 종속성 대신 합성을 이용해 의존성을 약화시킬 수 있다.
의존성을 약화시키는 방향으로 리팩터링하라.

5. 마지막 코스

어떤 시점이 되면 다른 개발자와의 충돌 위험을 감수하고, 그 코드를 새로운 코드 베이스로 전송해야 한다는 것을 의미한다.
저자는 이것을 마지막 코스라고 부른다.
마지막 단계에서는 모든 코드와 자산을 새 프로젝트로 전송한 다음, 모든 것이 잘 돌아가도록 만들어야 한다.

3. 신뢰할 만한 리팩터링

신뢰할 수 있는 리팩터링의 비결은 테스트이다.
코드의 테스트 범위가 양호하다면 코드를 훨씬 자유롭게 변경할 수 있다.
테스트가 없는 경우, 추가하는 프로세스를 도입하여 리팩터링을 진행하면 좋다.

4. 리팩터링을 하지 않는 경우

리팩터링의 좋은 점은 코드를 개선할 방법을 생각하게 한다는 것이다.
리팩터링의 단점은 어느 순간에, 그것이 Emacs처럼 수단이 아닌 목적이 될 수도 있다는 것이다.
Emacs는 텍스트 편집기, 개발 환경, 웹 브라우저, 운영 체제, 그리고 포스트 아포칼립스 롤플레잉 게임이다.
이 거리에서 일할 때는 충분히 좋은 코드와 가치에 대한 이해를 기본으로 길러야 한다.
충분히 좋은 코드에 대한 기준은 다음과 같다.
리팩터링하는 유일한 이유가 “이것이 더 우아한가”라면 이것은 커다란 위험 신호다.
우아하다는 것은 주관적일 뿐만 아니라 모호하고 의미가 없기 때문이다.
다음과 같이 확실한 이점이 담긴 리팩터링의 이유를 생각해 내도록 노력하라.
“리팩터링은 구성 요소를 사용할 때마다 작성해야 하는 상용 코드의 양을 줄임으로써 구성 요소를 사용하기 쉽게 만든다”
“리팩터링을 통해 새로운 라이브러리로 이동할 것이다”
“구성 요소 X에 대한 의존성을 없앨 수 있다”
대상의 구성 요소가 최소한의 구성 요소 집합에 의존하는가?
이는 나중에 쉽게 이동하거나 리팩터링할 수 있다는 것을 의미한다.
책의 리팩터링 예제는 코드의 경직된 부분을 식별하는 데 도움이 되지 않을 수 있다. 그렇다면 좀 더 확실한 개선 방안이 떠오를 때까지 미루는 것이 좋다.
테스트 범위가 아직 부족한가?
특히 구성 요소에 너무 많은 종속성이 있는 경우, 이는 리팩터링을 피해야 하는 즉각적인 위험 신호이다.
구성 요소에 대한 테스트가 부족하다는 것은 자신이 하고 있는 일을 모른다는 것을 의미하므로 리팩터링을 멈춰야 한다.
공통적인 의존 관계인가?
즉, 상당히 좋은 테스트 적용 범위와 정당성이 있더라도 팀원의 작업 흐름을 방해해 팀의 작업 환경에 영향을 미칠 수 있다.
이러한 비용을 보상하기에 여러분이 추구하는 이득이 충분하지 않다면 리팩터링을 뒤로 미루는 것을 고려해야 한다.

5. 요약

표면에 드러난 것보다 더 많은 장점이 있으므로 리팩터링을 받아들여라.
점진적으로 대규모 아키텍처를 변경할 수 있다.
대규모 리팩터링 작업에서 발생할 수 있는 잠재적인 문제를 줄이기 위해 테스트를 사용하라.
비용뿐만 아니라 위험도 추정하라.
대규모 아키텍처를 변경할 때는 점진적인 작업을 위해 항상 마음 속에 혹은 어딘가 적힌 로드맵을 갖고 있어야 한다.
리팩터링할 때 밀접하게 연결된 종속성과 같은 장애물을 제거하기 위해 종속성 주입을 사용하라. 동일한 기술로 코드의 경직도를 줄이라.
득보다 실이 더 클 때는 리팩터링하지 않거나 뒤로 미루는 것을 고려하라.