11. API 리팩터링
#
11.1 질의 함수와 변경 함수 분리하기- 겉보기 부수효과(observable side effect)가 전혀 없이 값을 반환해주는 함수를 추구해야 함
- 겉보기 부수효과: 데이터 값이 변경되는 것, 외부로 입출력이 있는 것
- 언제 어디서든 호출되도 문제가 없음
- 명령-질의 분리(command-query separation) 라고도 함
#
11.2 매개 변수화하기- 리터럴 값만 다른 함수가 있다면 매개변수화 해서 함수의 재사용성을 늘리는 전략
#
11.3 플래그 인수 제거하기- 인자에 boolean, enum, string이 들어가면 의심해 볼 수 있음
- 플래그 인수는 호출 할 수 있는 함수가 무엇이고 어떻게 해야하는지 파악이 어려워짐
- 플래그 인수가 둘 이상이면 함수 하나가 너무 많은 일을 하고 있다는 신호
#
11.4 객체 통째로 넘기기- 객체를 통째로 넘기면 좋은점
- 변화에 대응하기 쉬움 (함수에 인자가 더 필요하면 객체에 담을 수 있음)
- 가독성 증가
- 로직 중복 제거
- 함수가 레코드(객체)에 의존하기를 원치 않을땐 X
- 객체의 일부를 꺼내 그것으로 무엇을 하는 로직이 있다면, 이는 해당 객체에 메소드화 할 수 있다는 신호
#
11.5 매개변수를 질의 함수로 바꾸기- 매개변수 목록은
- 중복을 피하는게 좋음
- 짧을수록 좋음
- 저자는 호출하는 쪽을 간소화하고, 피호출 함수에 책임을 지게 만드는 구조를 주로 다룸
- 물론 해당 클래스가 그정도의 책임을 가져도 될 경우에만!
- 그래서 해당 리팩터링 시, 피호출자(리팩터링 대상)의 클래스가 과도한 의존성을 지니게 된다면 주의해야 함
- 리팩터링 대상 함수는 참조 투명해야 함
- 참조 투명: 똑같은 값에 항상 같은 결과 -> 해당 함수가 가변 전역 변수를 이용하는 일이 없어야 함
#
11.6 질의 함수를 매개변수로 바꾸기- 11.5 와 반대되는 리팩터링
- 클래스 설계 시 책임의 소재에 따라 달라질수 있는 문제
- 매개변수 객체가 참조 투명하지 않다면 해당 함수도 참조 투명하지 않음
- 이때 해당 리팩터링 적용 가능
- 단점은 호출자가 매개변수로 어떤 값을 보내야 할 지 알아야 함
- 결국 설계실력을 닦아야 하는 문제로 귀결
- 자바스크립트, 파이썬 등의 일부 언어에서는 객체 안에 데이터를 직접 얻어 낼 수 있는 방법이 항상 존재 하지만,
- 해당 클래스는 불변용으로 설계한 것을 알리는 것만으로도 좋은 효과를 누릴 수 있음
#
11.7 세터 제거하기- 외부에 세터를 제공하지 않음으로 해당 필드는 불변이라는 의도를 알릴 수 있음
- 객체 생성 후 수정되지 않길 원하는 필드라면 세터 제공 X
- 세터 제거하기 리팩터링이 필요한 2가지 상황
- 무조건 접근자 메서드를 통해 필드를 다루려 할 때 (생성자에서 세터..)
- 클라이언트에서 생성 스크립트를 사용해 객체를 생성할 때
- 생성 스크립트: 생성자로 객체를 생성하고 일련의 세터로 객체를 완성하는 형태
#
11.8 생성자를 팩터리 함수로 바꾸기- 생서자의 한계
- 자바 생성자는 그 생성자를 정의한 클래스의 인스턴스만 반환 가능 (하위, 프록시 X)
- 기본 이름보다 더 적절한 이름 불가
- 일반 함수가 오길 기대하는 자리에 쓸 수 없음
- 팩터리 함수는 이런 제약이 없음 -> 원하는 적잘한 다른 무언가로 대체 가능
#
11.9 함수를 명령으로 바꾸기- 함수를 클래스화 하여 메세지로 수행할 수 있게 함
- 이런 클래스를
명령(command) (객체)
라고 함- 명령 객체는 대부분 메서드 하나로 구성됨, 요청해 실행하는 것이 이 객체의 목적
- undo 보조 연산, 현재 수명주기를 정밀하게 만들어주는 메서드 제공, 상속과 훅 사용을 이용해 맞춤형 제공 등 다양한 기능을 제공
- 유연성은 언제나 복잡성을 키우고 얻는 대가니 잘 판단
#
11.10 명령을 함수로 바꾸기- 11.9 와 반대
- 로직이 크게 복잡하지 않다면 명령 객체를 굳이 만들 필요 없음
#
11.11 수정된 값 반환하기- 함수 내에서 전역 변수나, 아규먼트의 객체를 수정하지 않고, 새로운 값으로 반환
- 함수 내에서 수정할 경우 변경의 추적이 어려움
#
11.12 오류 코드를 예외로 바꾸기- 오류 코드 검사는 매번 검사해줘야하는 불편함이 있음
- 예외는 상위로 던지거나 하는 독자적인 매커니즘을 사용하여 다른 객체에 오류를 핸들링 하는 역할을 넘길 수 있음
- 예외는 정확히 예상 밖의 동작일 때만 쓰여야 함
- 검사 예외, 비검사 예외 잘 구분해서 사용해야겠다
#
11.13 예외를 사전확인으로 바꾸기- 예외는
뜻밖의 오류
, 즉 말그대로 예외적으로 동작할 때만 쓰여야 함 - 예외를 던지기 전, 함수 호출 전에 조건을 검사할 수 있다면 조건 검사로 대체하자