1. 변수 쪼개기
- 하나의 값이 여러 목적으로 사용된다면 혼란과 버그를 낳는다.
- 역할 하나당 변수 하나다. 여러 용도로 쓰인 변수는 코드를 읽는 이에게 커다란 혼란을 주기 때문이다.
절차
- 변수를 선언한 곳과 값을 처음 대입하는 곳에서 변수 이름을 바꾼다.
- 가능하면 이때 불변으로 선언한다.
- 이 변수에 두 번째로 값을 대입하는 곳 앞까지의 모든 참조를 새로운 변수 이름으로 바꾼다.
- 두 번째 대입 시 변수를 원래 이름으로 다시 선언한다.
- 테스트한다.
- 반복한다. 매 반복에서 변수를 새로운 이름으로 선언하고 다음번 대입 때까지의 모든 참조를 새 변수명으로 바꾼다. 이 과정을 마지막 대입까지 반복한다.
2. 필드 이름 바꾸기
- 데이터 구조는 프로그램을 이해하는 데 큰 역할을 한다.
- 데이터 구조는 무슨 일이 벌어지는지를 이해하는 열쇠다.
- 데이터 구조가 중요한 만큼 반드시 깔끔하게 관리해야 한다.
절차
- 레코드의 유효 범위가 제한적이라면 필드에 접근하는 모든 코드를 수정한 후 테스트한다. 이후 단계는 필요 없다.
- 레코드가 캡슐화되지 않았다면 우선 레코드를 캡슐화한다.
- 캡슐화된 객체 안의 private 필드명을 변경하고, 그에 맞게 내부 메서드들을 수정한다.
- 테스트한다.
- 생성자의 매개변수 중 필드와 이름이 겹치는 게 있다면 함수 선언 바꾸기로 변경한다.
- 접근자들의 이름도 바꿔준다.
3. 파생 변수를 질의 함수로 바꾸기
- 가변 데이터는 소프트웨어에 문제를 일으키는 가장 큰 골칫거리에 속한다.
- 가변 데이터는 한 쪽 코드에서 수정한 값이 연쇄효과를 일으켜 다른 쪽 코드에 원인을 찾기 어려운 문제를 야기하기도 한다.
- 가변 데이터를 완전히 배제하기란 현실저으로 불가능할 때가 많지만, 가변 데이터의 유효 범위를 가능한 한 좁혀야 한다고 주장한다.
- 효과가 좋은 방법으로, 값을 쉽게 계산해낼 수 있는 변수들을 모두 제거할 수 있다.
- 계산 과정을 보여주는 코드 자체가 데이터의 의미를 더 분명히 드러내는 경우도 자주 있으며 변겨된 값을 깜빡하고 결과 변수에 반영하지 않는 실수를 막아준다.
절차
- 변수 값이 갱신되는 지점을 모두 찾는다. 필요하면 변수 쪼개기를 활용해 각 갱신 지점에서 변수를 분리한다.
- 해당 변수의 값을 계산해주는 함수를 만든다.
- 해당 변수가 사용되는 모든 곳에 어셔선을 추가하여 함수의 계산 결과가 변수의 값과 같은지 확인한다.
- 테스트한다.
- 변수를 읽는 코드를 모두 함수 호출로 대체한다.
- 테스트한다.
- 변수를 선언하고 갱신하는 코드를 죽은 코드 제거하기로 없앤다.
4. 참조를 값으로 바꾸기
- 객체를 다른 객체에 중첩하면 내부 객체를 참조 혹은 값으로 취급할 수 있다.
- 참조냐 값이냐의 차이는 내부 객체의 속성을 갱신하는 방식에서 가장 극명하게 드러난다.
- 참조로 다루는 경우에는 내부 객체는 그대로 둔 채 그 객체의 속성만 갱신하며, 값으로 다루는 경우에는 새로운 속성을 담은 객체로 기존 내부 객체를 통째로 대체한다.
- value object는 대체로 자유롭게 활용하기 좋은데, 특히 불변이기 때문이다.
- 특정 객체를 여러 객체에서 공유하고자 한다면, 그래서 공유 객체의 값을 변경했을 때 이를 관련 객체 모두에게 알려줘야 한다면 공유 객체를 참조로 다뤄야 한다.
절차
- 후보 클래스가 불변인지, 혹은 불변이 될 수 있는지 확인한다.
- 각각의 세터를 하나씩 제거한다.
- 이 값 객체의 필드들을 사용하는 동치성비교 메서드를 만든다.
5. 값을 참조로 바꾸기
- 고객 데이터를 갱신할 일이 없다면 값이나 참조로 다루는 방식이든 상관없다. 같은 데이터를 여러벌 복사하는게 조금 꺼림칙할지 모르지만, 별달리 문제되는 경우는 많지 않아서 흔히 사용하는 방식이다.
- 논리적으로 같은 데이터를 물리적으로 복제해 사용할 때 가장 크게 문제되는 상황은 그 데이터를 갱신해야 할 때다
- 모든 복제본을 찾아서 빠짐없이 갱신해야 하며, 하나라도 놓치면 데이터 일관성이 깨져버린다. 이런 상황이라면 모두 참조로 바꿔주는 게 좋다.
- 각 엔티티를 표현하는 객체를 한 번만 만들고, 객체가 필요한 곳에서는 모두 이 저장소로부터 얻어 쓰는 방식이 된다.
절차
- 같은 부류에 속하는 객체들을 보관할 저장소를 만든다.
- 생성자에서 이 부류의 객체들 중 특정 객체를 정확히 찾아내는 방법이 있는지 확인한다.
- 호스트 객체의 생성자들을 수정하여 필요한 객체를 이 저장소에서 찾도록 한다. 하나 수정할 때마다 테스트한다.
6. 매직 리터럴 바꾸기
- 코드 자체가 뜻을 분명하게 드러내는 게 좋다.
방법
- 상수를 선언하고 매직 리터럴을 대입한다.
- 해당 리터럴이 사용되는 곳을 모두 찾는다.
- 찾은 곳 가각에서 리터럴이 새 상수와 똑같은 의미로 쓰였는지 확인하여, 같은 의미라면 상수로 대체한 후 테스트한다.
출처
리팩터링 2판