본문 바로가기
Study/Refactoring

리팩터링 챕터 9

by irerin07 2023. 8. 27.
728x90

9장 - 데이터 조직화

9.1 변수 쪼개기

배경

  • 변수에 대입이 여러번 이뤄진다면 여러가지 역할을 수행한다는 신호이므로 역할 하나당 하나의 변수로 쪼개야 한다.

절차

  1. 변수를 선언한 곳과 값을 처음 대입하는 곳에서 변수 이름을 바꾼다.
    1. 이후의 대입이 항상 i = i + <무언가> 형태라면 수집 변수이므로 쪼개서는 안된다.
  2. 가능하면 불변으로 선언한다.
  3. 이 변수에 두 번쨰로 값을 대입하는 곳 앞까지의 모든 참조(이 변수가 쓰인 곳)를 새로운 변수 이름으로 바꾼다.
  4. 두 번쨰 대입 시 변수를 원해 이름으로 다시 선언한다.
  5. 테스트한다.
  6. 반복한다. 매 반복에서 변수를 새로운 이름으로 선언하고 다음번 대입 때까지의 모든 참조를 새 변수명으로 바꾼다. 이 과정을 마지막 대입까지 반복한다.

예시

9.2 필드 이름 바꾸기

배경

  • 데이터 구조는 굉장히 중요하며 반드기 깔끔하게 관리해야 한다.
  • 데이터 구조에 대한 이해가 깊어지며 필드의 이름을 바꾸고 싶어질 수 있는데 클래스에서도 마찬가지다.
    • 게터/세터 메서드는 클래스 사용자 입장에서는 필드와 다를바 없기 때문에 이들의 이름 바꾸기 역시 레코드 구조체의 필드 이름 바구기와 똑같이 중요하다.

절차

  1. 레코드의 유효 범위가 제한적이라면 필드에 접근하는 모든 코드를 수정한 후 테스트한다. 이후 단계는 필요없다.
  2. 레코드가 캡슐화 되어있지 않다면 우선 레코드를 캡슐화 한다.
  3. 캡슐화된 객체 안의 private 필드명을 변경하고, 그에 맞게 내부 메서드들을 수정한다.
  4. 테스트한다.
  5. 생성자의 매개변수 중 필드와 이름이 겹치는 게 있다면 함수 선언 바꾸기로 변경한다.
  6. 접근자들의 이름도 바꿔준다.

예시

9.3 파생 변수를 질의 함수로 바꾸기

배경

  • 가변 데이터는 서로 다른 두 코드를 이상한 방식으로 결합해 큰 골칫거리이다. 그렇기 때문에 완전히 배제할 수는 없더라도 그 유효 범위를 최대한 좁혀야 한다.
  • 값을 쉽게 계산해낼 수 있는 변수들은 제거하면 코드 자체가 의미를 더 분명히 드러내기도 하고 변경된 값을 깜빡하고 결과 변수에 반영하지 않는 실수를 줄여준다.
  • 예외적으로 새로운 데이터 구조를 만드는 변형 연산이라면 비록 계산 코드로 대체할 수 있다고 하더라도 그대로 두는 것도 좋다. (변형연산transformation operation?)
    • 변형 연산의 두가지 유형
      1. 데이터 구조를 감싸며 그 데이터에 기초해 계산한 결과를 속성으로 제공하는 객체
      2. 데이터 구조를 받아 다른 데이터 구조로 변환해 반환하는 함수

절차

  1. 변수 값이 갱신되는 지점을 모두 찾는다. 필요하면 변수 쪼개기를 활용해 각 갱신 지점에서 변수를 분리한다.
  2. 해당 변수의 값을 계산해주는 함수를 만든다.
  3. 해당 변수가 사용되는 모든 곳에 어서션을 추가하여 함수의 계산 결과가 변수의 값과 같은지 확인한다.
    1. 필요시 변수 캡슐화하기를 적용해 어서션이 들어간 장소를 만든다.
  4. 테스트한다.
  5. 변수를 읽는 코드를 모두 함수 호출로 대체한다.
  6. 테스트한다.
  7. 변수를 선언하고 갱신하는 코드를 죽은 코드 제거하기로 없앤다.

예시

9.4 참조를 값으로 바꾸기

반대 리팩터링 : 값을 참조로 바꾸기

배경

  •  
  • 값 객체의 이런 특성 때문에 특정 객체를 여러 객체에서 공유하고자 한다면, 그래서 공유 객체의 값을 변경했을 때 이를 관련 객체 모두에 알려줘야 한다면 공유 객체를 참조로 다뤄야 한다.

절차

  1. 후보 클래스가 불변인지, 혹은 불변이 될 수 있는지 확인한다.
  2. 각각의 세터를 하나씩 제거한다.
  3. 이 값 객체의 필드들을 사용하는 동치성 비교 메서드를 만든다.
    1. 동치성 비교 메서드 오버라이드시 해시코드 생성 메서드도 함께 오버라이드 해야한다.

예시

9.5 값을 참조로 바꾸기

반대 리팩터링 : 참조를 값으로 바꾸기

배경

  • 논리적으로 같은 데이터를 물리적으로 복제해 사용할 때 가장 크게 문제되는 상황은 해당 데이터를 갱신해야 하는 경우이다.
  • 모든 복제본을 찾아 빠짐없이 갱신해야 하며, 하나라도 놓치면 데이터 일관성이 깨진다.
  • 이런 경우 복제된 데이터들을 모두 참조로 바꿔주는 게 좋다.
  • 값을 참조로 바꾸면 엔티티 하나당 객체도 단 하나만 존재하게 되는데, 각 엔티티를 표현하는 객체를 한 번만 만들고, 객체가 필요한 곳에서는 객체들을 한데 모아놓고 클라이언트들의 접근을 관리하는 저장소로부터 얻어 쓰는 방식이 된다.(?)

절차

  1. 같은 부류에 속하는 객체들을 보관할 저장소를 만든다.(이미 있다면 생략)
  2. 생성자에서 이 부류의 객체들 중 특정 객체를 정확히 찾아내는 방법이 있는지 확인한다.
  3. 호스트 객체의 생성자들을 수정하여 필요한 객체를 이 저장소에서 찾도록 한다. 하나 수정할 때마다 테스트한다.

예시

9.6 매직 리터럴 바꾸기

배경

  • 매직 리터럴이란 소스코드 여러 곳에 등장하는 일반적인 리터럴 값을 말한다.
  • 이런 리터럴 값을 그 자체로는 의미를 명확히 알려주지 못하는 경우가 많다.
  • 이보다는 코드 자체가 뜻은 분명하게 드러낼 수 있도록 상수를 정의하고 매직 리터럴 대신 상수를 사용하도록 바꾸면 된다.

절차

  1. 상수를 선언하고 매직 리터럴을 대입한다.
  2. 해당 리터럴이 사용되는 곳을 모두 찾는다.
  3. 찾은 곳 각각에서 리터럴이 새 상수와 똑같은 의미로 쓰였는지 확인하여, 같은 의미라면 상수로 대체한 후 테스트한다.

예시

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