리팩터링 7장

박경준·2022년 12월 9일
0

리팩터링 책 요약

목록 보기
7/7

캡슐화

모듈을 분리하는 중요한 기준은 각 모듈이 자신을 제외한 다른 부분에 드러내지 않아야 할 비밀을 얼마나 잘 숨기느냐에 있다.

1. 레코드 캡슐화하기

가변 데이터를 저장하는 용도로는 레코드보다 객체가 좋다. 객체를 사용하면 어떻게 저장했는지를 숨긴 채 세 가지 값을 각각의 메서드로 제공할 수 있다. 사용자는 무엇이 저장된 값이고 무엇이 계산된 값인지 알 필요가 없다.

  1. 레코드를 담은 변수를 캡슐화한다. 레코드를 캡슐화하는 함수의 이름은 검색하기 쉽게 지어준다.
  2. 레코드를 감싼 단순한 클래스로 해당 변수의 내용을 교체한다. 이 클래스에 원본 레코드를 반환하는 접근자도 정의하고 변수를 캡슐화하는 함수들이 이 접근자를 사용하도록 수정한다.
  3. 테스트
  4. 원본 레코드 대신 새로 정의한 클래스 타입의 객체를 반환하는 함수들을 새로 만든다.
  5. 레코드를 반환하는 예전 함수를 사용하는 코드를 4에서 만든 새함수를 사용하도록 바꾼다. 필드에 접근할 때는 객체의 접근자를 사용한다. 적절한 접근자가 없다면 추가한다. 한 부분을 바꿀 때마다 테스트한다. 중첩된 구조처럼 복잡한 레코드라면 먼저 데이터를 갱신하는 클라이언트들에 주의해서 살펴본다. 클라이언트가 데이터를 읽기만한다면 데이터의 복제본이나 읽기전용 프락시를 반환할지 고려해보자.
  6. 클래스에서 원본 데이터를 반환하는 접근자와 원본 레코드를 반환하는 함수들을 제거한다.
  7. 테스트
  8. 레코드의 필드도 데이터 구조인 중첩 구조라면 레코드 캡슐화하기와 컬렉션 캡슐화하기를 재귀적으로 적용한다.

컬렉션 캡슐화하기

컬렉션 변수로의 접근을 캡슐화하면서 게터가 컬렉션 자체를 반환하도록 한다면, 그 컬렉션을 감싼 클래스가 눈치채지 못하는 상태에서 컬렉션의 원소들이 바뀌어버릴 수 있다.

  1. 아직 컬렉션을 캡슐화하지 않았다면 변수 캡슐화하기부터 한다.
  2. 컬렉션에 원소를 추가/제거하는 함수를 추가한다. 컬렉션 자체를 통째로 바꾸는 세터는 제거한다. 세터를 제거할 수 없다면 인수로 받은 컬렉션을 복제해 저장하도록 만든다.
  3. 컬렉션을 참조하는 부분을 모두 찾는다. 컬렉션의 변경자를 호출하는 코드가 모두 앞에서 추가한 추가/제거 함수를 호출하도록 수정한다. 하나씩 수정할 때마다 테스트한다.
  4. 컬렉션 게터를 수정해서 원본 내용을 수정할 수 없는 읽기전용 프락시나 복제본을 반환하게 한다.
  5. 테스트

기본형을 객체로 바꾸기

단순한 출력 이상의 기능이 필요해지는 순간 그 데이터를 표현하는 전용 클래스를 정의한다.

  1. 아직 변수를 캡슐화하지 않았다면 캡슐화한다.
  2. 단순한 값 클래스를 만든다. 생성자는 기존 값을 인수로 받아서 저장하고, 이 값을 반환하는 게터를 추가한다.
  3. 값 클래스의 인스턴스를 새로 만들어서 필드에 저장하도록 세터를 수정한다. 이미 있다면 필드의 타입을 적절히 변경한다.
  4. 새로 만든 클래스의 게터를 호출한 결과를 반환하도록 게터를 수정한다.
  5. 테스트
  6. 함수 이름을 바꾸면 원본 접근자의 동작을 더 잘 드러낼 수 있는지 검토한다. 참조를 값으로 바꾸거나 값을 참조로 바꾸면 새로 만든 객체의 역할(값 또는 참조 객체)이 더 잘 드러나는지 검토한다.

임시 변수를 질의 함수로 바꾸기

임시 변수는 코드가 반복되는걸 줄이고 값의 의미를 설명할 수도 있다. 그런데 더 나아가 임시 변수를 함수로 표현할수도 있다. 추출한 함수와 원래 함수의 경계가 더 분명해지는데 그러면 부자연스러운 의존 관계나 부수효과를 찾고 제거하는데 도움이 된다.

  1. 변수가 사용되기 전에 값이 확실히 결정되는지, 변수를 사용할 때마다 계산 로직이 매번 다른 결과를 내지는 않는지 확인한다.
  2. 읽기전용으로 만들 수 있는 변수는 읽기전용으로 만든다.
  3. 테스트
  4. 변수 대입문을 함수로 추출한다. 변수와 함수가 같은 이름을 가질 수 없다면 함수 이름을 임시로 짓는다. 또한, 추출한 함수가 부수효과를 일으키지는 않는지 확인한다. 부수효과가 있다면 질의 함수와 변경 함수 분리하기로 대처한다.
  5. 테스트
  6. 변수 인라인하기로 임시 변수를 제거한다.
profile
빠굥

0개의 댓글