728x90
9장 - 데이터 조직화
9.1 변수 쪼개기
배경
- 변수에 대입이 여러번 이뤄진다면 여러가지 역할을 수행한다는 신호이므로 역할 하나당 하나의 변수로 쪼개야 한다.
절차
- 변수를 선언한 곳과 값을 처음 대입하는 곳에서 변수 이름을 바꾼다.
- 이후의 대입이 항상
i = i + <무언가>
형태라면 수집 변수이므로 쪼개서는 안된다.
- 이후의 대입이 항상
- 가능하면 불변으로 선언한다.
- 이 변수에 두 번쨰로 값을 대입하는 곳 앞까지의 모든 참조(이 변수가 쓰인 곳)를 새로운 변수 이름으로 바꾼다.
- 두 번쨰 대입 시 변수를 원해 이름으로 다시 선언한다.
- 테스트한다.
- 반복한다. 매 반복에서 변수를 새로운 이름으로 선언하고 다음번 대입 때까지의 모든 참조를 새 변수명으로 바꾼다. 이 과정을 마지막 대입까지 반복한다.
예시
9.2 필드 이름 바꾸기
배경
- 데이터 구조는 굉장히 중요하며 반드기 깔끔하게 관리해야 한다.
- 데이터 구조에 대한 이해가 깊어지며 필드의 이름을 바꾸고 싶어질 수 있는데 클래스에서도 마찬가지다.
- 게터/세터 메서드는 클래스 사용자 입장에서는 필드와 다를바 없기 때문에 이들의 이름 바꾸기 역시 레코드 구조체의 필드 이름 바구기와 똑같이 중요하다.
절차
- 레코드의 유효 범위가 제한적이라면 필드에 접근하는 모든 코드를 수정한 후 테스트한다. 이후 단계는 필요없다.
- 레코드가 캡슐화 되어있지 않다면 우선 레코드를 캡슐화 한다.
- 캡슐화된 객체 안의 private 필드명을 변경하고, 그에 맞게 내부 메서드들을 수정한다.
- 테스트한다.
- 생성자의 매개변수 중 필드와 이름이 겹치는 게 있다면 함수 선언 바꾸기로 변경한다.
- 접근자들의 이름도 바꿔준다.
예시
9.3 파생 변수를 질의 함수로 바꾸기
배경
- 가변 데이터는 서로 다른 두 코드를 이상한 방식으로 결합해 큰 골칫거리이다. 그렇기 때문에 완전히 배제할 수는 없더라도 그 유효 범위를 최대한 좁혀야 한다.
- 값을 쉽게 계산해낼 수 있는 변수들은 제거하면 코드 자체가 의미를 더 분명히 드러내기도 하고 변경된 값을 깜빡하고 결과 변수에 반영하지 않는 실수를 줄여준다.
- 예외적으로 새로운 데이터 구조를 만드는 변형 연산이라면 비록 계산 코드로 대체할 수 있다고 하더라도 그대로 두는 것도 좋다. (변형연산transformation operation?)
- 변형 연산의 두가지 유형
- 데이터 구조를 감싸며 그 데이터에 기초해 계산한 결과를 속성으로 제공하는 객체
- 데이터 구조를 받아 다른 데이터 구조로 변환해 반환하는 함수
- 변형 연산의 두가지 유형
절차
- 변수 값이 갱신되는 지점을 모두 찾는다. 필요하면 변수 쪼개기를 활용해 각 갱신 지점에서 변수를 분리한다.
- 해당 변수의 값을 계산해주는 함수를 만든다.
- 해당 변수가 사용되는 모든 곳에 어서션을 추가하여 함수의 계산 결과가 변수의 값과 같은지 확인한다.
- 필요시 변수 캡슐화하기를 적용해 어서션이 들어간 장소를 만든다.
- 테스트한다.
- 변수를 읽는 코드를 모두 함수 호출로 대체한다.
- 테스트한다.
- 변수를 선언하고 갱신하는 코드를 죽은 코드 제거하기로 없앤다.
예시
9.4 참조를 값으로 바꾸기
반대 리팩터링 : 값을 참조로 바꾸기
배경
- 값 객체의 이런 특성 때문에 특정 객체를 여러 객체에서 공유하고자 한다면, 그래서 공유 객체의 값을 변경했을 때 이를 관련 객체 모두에 알려줘야 한다면 공유 객체를 참조로 다뤄야 한다.
절차
- 후보 클래스가 불변인지, 혹은 불변이 될 수 있는지 확인한다.
- 각각의 세터를 하나씩 제거한다.
- 이 값 객체의 필드들을 사용하는 동치성 비교 메서드를 만든다.
- 동치성 비교 메서드 오버라이드시 해시코드 생성 메서드도 함께 오버라이드 해야한다.
예시
9.5 값을 참조로 바꾸기
반대 리팩터링 : 참조를 값으로 바꾸기
배경
- 논리적으로 같은 데이터를 물리적으로 복제해 사용할 때 가장 크게 문제되는 상황은 해당 데이터를 갱신해야 하는 경우이다.
- 모든 복제본을 찾아 빠짐없이 갱신해야 하며, 하나라도 놓치면 데이터 일관성이 깨진다.
- 이런 경우 복제된 데이터들을 모두 참조로 바꿔주는 게 좋다.
- 값을 참조로 바꾸면 엔티티 하나당 객체도 단 하나만 존재하게 되는데, 각 엔티티를 표현하는 객체를 한 번만 만들고, 객체가 필요한 곳에서는 객체들을 한데 모아놓고 클라이언트들의 접근을 관리하는 저장소로부터 얻어 쓰는 방식이 된다.(?)
절차
- 같은 부류에 속하는 객체들을 보관할 저장소를 만든다.(이미 있다면 생략)
- 생성자에서 이 부류의 객체들 중 특정 객체를 정확히 찾아내는 방법이 있는지 확인한다.
- 호스트 객체의 생성자들을 수정하여 필요한 객체를 이 저장소에서 찾도록 한다. 하나 수정할 때마다 테스트한다.
예시
9.6 매직 리터럴 바꾸기
배경
- 매직 리터럴이란 소스코드 여러 곳에 등장하는 일반적인 리터럴 값을 말한다.
- 이런 리터럴 값을 그 자체로는 의미를 명확히 알려주지 못하는 경우가 많다.
- 이보다는 코드 자체가 뜻은 분명하게 드러낼 수 있도록 상수를 정의하고 매직 리터럴 대신 상수를 사용하도록 바꾸면 된다.
절차
- 상수를 선언하고 매직 리터럴을 대입한다.
- 해당 리터럴이 사용되는 곳을 모두 찾는다.
- 찾은 곳 각각에서 리터럴이 새 상수와 똑같은 의미로 쓰였는지 확인하여, 같은 의미라면 상수로 대체한 후 테스트한다.
예시
728x90
'Study > Refactoring' 카테고리의 다른 글
리팩터링 11 (0) | 2023.08.29 |
---|---|
리팩터링 챕터 10 (0) | 2023.08.28 |
리팩토링 챕터 8 (0) | 2023.07.25 |
리팩터링 챕터7 (0) | 2023.07.17 |
리팩터링 챕터 6 (0) | 2023.07.16 |