[리팩터링 2판] 3, 4장
3.1 기이한 이름
코드는 단순 명료 --> 이름을 통해 무슨 일을 하는지, 사용 방법을 알 수 있어야한다
- 함수 선언 바꾸기
- 변수 이름 바꾸기
- 필드 이름 바꾸기
이후 문맥 파악 시간 절약 가능
3.2 중복 코드
코드 중복 시 서로 차이점은 없는지 살펴봐야하는 부담
하나 변경 시 비슷한 코드들 모두 수정해야함
- 함수 추출하기
- 문장 슬라이드 하기 : 코드가 비슷하지만 완전 똑같지 않을 시 비슷한 부분 모으기
- 메서드 올리기 : 파생 서브 클래스 내 코드 중복시 부모로 이동
3.3 긴 함수
짧은 함수 구성 시 이해, 공유, 선택이 쉬워짐
함수명을 의도가 드러나게, 잘 지으면 본문 코드를 보러 갈 필요가 없어짐
주석을 달아야할 부분은 무조건 함수로 만들기
함수를 짧게 만드는 작업의 99%는 함수 추출하기가 차지 : 따로 묶어 빼내기
함수가 매개변수, 임시변수를 많이 사용할 시 추출이 어려움 -> 임시변수를 질의함수로 변경, 매개변수를 객체로 만들어 넘기기
그래도 임시, 매개 변수가 많다면 함수를 명령으로 바꾸기 적용 고려
추출할 부분은 주석을 참고하기
조건문이 있을 시 조건문 분해하기, switch-case문은 함수 추출하기, switch 문이 여러개라면 조건문을 다형성으로 변경
반복문 내 성격이 다른 두가지 작업이 섞여있을 땐 반복문 쪼개기
3.4 긴 매개변수 목록
다른 매개변수에서 얻어올 수 있는 매개변수가 있을 시 매개변수를 질의 함수로 바꾸기를 통해 제거
사용중인 데이터구조에서 값들을 몇개 뽑아서 별개의 매개변수로 전달한다면 객체 통째로 넘기기 적용
항상 함께 전달되는 매개변수는 매개변수 객체 만들기를 통해 하나로 묶기
플래그 변수 인수 제거하기
여러 함수를 클래스로 묶은 후 공통의 값을 클래스 필드로 정의
3.5 전역 데이터
전역 데이터 주의하기, 적게 쓰기
변수 캡슐화하기를 통해 함수로 감싸 해당 데이터가 어디서 변경되는지 추적할 수 있음
3.6 가변 데이터
함수형 프로그래밍에서는 데이터는 항상 불변으로 두고, 변경 하고 싶다면 복사본을 만들어 반환해야함
변수 캡슐화하기를 통해 함수를 거쳐야 값을 수정할 수 있도록 만들기
변수 쪼개기
문장 슬라이드하기와 함수 추출하기를 통해 갱신로직은 다른 코드와 떨어뜨려놓는 것이 좋다
세터도 가능하면 제거하기
값을 다른 곳에서 설정하는 가변 데이터는 파생 변수를 질의 함수로 바꾸기를 통해. 해결?
여러 함수를 클래스로 묶기,여러 함수를 변환함수로 묶기를 통해 변수를 갱신하는 코드들의 유효 범위를 제한하기
3.7 뒤엉킨 변경
한 곳을 수정 할 때 여러 곳을 같이 수정해야하는 경우
- 함수 내 한 동작만 하는 것이 아닌 여러 기능이 섞임 --> 분리하기
3.8 산탄총 수술
코드 변경 시 자잘하게 수정해야하는 클래스가 많음
- 한 기능이 여러 함수에 흩어짐 -->
3.9 기능 편애
자기가 속한 모듈의 함수나 데이터보다 다른 모듈의 함수, 데이터와 상호작용을 더 많이하는 것
해당 모듈로 함수 옮기기, 함수 추출하기 등 사용 가능
3.10 데이터 뭉치
데이터 항목 서너개가 여러번 함께 쓰일 시 클래스 추출하기를 통해 하나의 객체로 묶기
매서드 시그니처의 데이터 뭉치는 매개변수 객체 만들기, 객체 통째로 넘기기를 통해 매개변수 수를 줄이기
데이터 뭉치인지 판변 하는 법 : 값 하나 삭제 해보기
레코드 구조가 아닌 클래스로 만들기 권장
3.11 기본형 집착
기본형 (primitive type) 을 객체로 바꾸기!
타입 코드를 서브클래스로 바꾸기
조건부 로직을 다형성으로 바꾸기
3.12 반복되는 switch문
조건부 로직을 다형성으로 바꾸기
switch문의 경우 하나의 조건절을 추가할 때마다 다른 switch문도 모두 수정해야하기 때문
3.13 반복문
반복문을 파이프라인으로 바꾸기
3.14 성의 없는 요소
성의 없는 요소 제거하기 위해서는 함수인라인하기, 클래스 인라인하기 사용
상속을 사용했을 시에는 계층 합치기
3.15 추측성 일반화
미래를 대비해 작성한 코드 지우기
추상 클래스는 계층 합치기로 제거
함수인라인하기, 클래스 인라인하기
사용되지 않는 매개변수는 함수 선언 바꾸기 등을 통해 제거
테스트코드만 존재한다면 죽은 코드 제거하기로 제거
3.16 임시 필드
필드값이 설정 될 때도 안될 때도 있음
클래스 추출하기 후 함수 옮기기를 통해 임시 필드 관련 코드를 새 클래스로 옮김
3.17 메시지 체인
한 객체에서 다른 객체를 얻을 때 연쇄적으로 다른 객체가 또 다른 객체를 요청하는 코드
- 클라이언트 코드에서 아래와 같이 불러올 시 중간 객체 내용 변경 되면 하나 하나 다 바꿔줘야함
- 하지만 managerName 과 같이 함수를 사용하면 함수에서만 내용을 바꾸면 됨
ex. managerName = aPerson.departmen.manager.name;
-> managerName = aPerson.managerName
3.18 중개자
캡슐화 과정에서 위임이 자주 활용 됨
중개자 제거하기를 통해 실제로 일하는 객체와 직접 소통하게 만들기
3.19 내부자 거래
함수 옮기기, 필드 옮기기를 통해 떨어뜨려 결합도 낮추기
여러 모듈이 같은 관심사를 공유한다면 제 3의 모듈을 만들거나 위임숨기기를 이용해 중간자를 만듦
상속 구조에서 자식이 부모에서 나올 때는 서브클래스를 위임으로 바꾸기, 슈퍼클래스를 위임으로 바꾸기 활용
-위임이 뭐임??? 원래 내가 해야할 작업을 다른 객체한데 주는 ? delegate
3.20 거대한 클래스
클래스 추출하기로 일부 필드를 따로 묶기
분리할 컴포넌트를 상속관계로 만드는게 좋다면 슈퍼 클래스 추출하기 혹은 타입코드를 서브클래스로 바꾸기
3.21 서로 다른 인터페이스의 대안 클래스들
ex. 버스 객체 - 운전 , 택시 객체 - 이동 있을 때 운전과 이동은 같은 기능을 함.. 이 둘의 인터페이스를 맞추기 위해 함수 옮기기 등 사용
3.22 데이터 클래스
데이터 필드, getter/setter 메소드로만 구성된 클래스
public 필드는 레코드 캡슐화하기로 숨기기
3.23 상속 포기
메서드 내리기, 필드 내리기 등 통해 서브 클래스를 만들어 부모에는 공통 된 부분만 만들기 -> 굳이 이렇게 할 이유는 없다
부모의 인터페이스를 따르지 않는다면 서브클래스를 위임으로 바꾸기, 슈퍼클래스를 위임으로 바꾸기를 이용해 상속에서 벗어나기
ex. 슈퍼 클래스가 운전 함수를 쓰고 있음. 자식이 운전의 기능은 쓰고 싶으나 그 인터페이스를 따르고 싶지 않음
3.24 주석
주석 대신 함수 추출하기
함수를 설명하는 대신 함수 선언 바꾸기
선행 조건을 명시 하고 싶다면 어서션 추가하기
주석을 남겨야하겠다는 생각이 들면 일단 주석이 필요 없는 코드로 리팩터링 해보기
뭘 할지 모를 때, 불확실한 부분에는 주석 달기
테스트 구축하기
4.1 자가 테스트 코드의 가치
대부분의 시간은 디버깅에 쓴다
모든 테스트를 완전 자동화하고 결과도 스스로 검사하게 만들기
테스트 - 코딩 - 리팩터링 순서
4.2 테스트 샘플 코드
지역
수요, 가격
생산자수
생산자 - 비용, 생산량 -> 수익
부족분, 총수익
4.3 첫 번째 테스트
js 용 테스트 프레임워크 모카 사용
- 테스트 코드를 블록 단위로 나워 블록에 테스트 스위트를 담는 구조
생산 부족분 테스트 코드
픽스처 : 테스트에 필요한 데이터, 객체
픽스처 속성 검증
실패하는 코드로 만들고 어디서 문제가 나타났는지 확인
assert, expect
4.4 테스트 추가
읽고 쓰는 접근자 테스트는 할 필요 없음
적은 수의 테스트로 큰 효과, 걱정되는 영역을 집중적으로 테스트
중복되는 픽스처를 const로 빼면 안되고 테스트 전에 항상 먼저 실행되는 beforeEach에 픽스처를 선언하기
4.5 픽스처 수정하기
테스트 단계 : 설정 - 실행 - 검증
초기 준비 작업 중 공통 부분을 beforeEach에 모아 처리하기도함
it 구문 당 하나의 검증만 하는 것이 좋음
4.6 경계조건 검사하기
문제가 생길 수 있는 경계 조건을 생각해보고, 집중적으로 테스트
0 일 때, -일 때, null 일 때 등