layout: post title: “Refactoring 11 API 리팩터링” date: 2022-08-29 23:51 categories: Refactoring study tags: cleanCode, study —
11 API 리팩터링
11.1 질의함수와 변경함수 분리하기
- 질의함수는 부수효과가 없어야한다. (command-query separation)
절차
- 대상 함수를 복제하고 질의 목적에 충실한 이름을 짓는다.
- 새 질의함수에서 부수효과를 모두 제거한다.
- 정적 검사를 수행한다.
- 원래 함수를 수행하는곳에서 반환값을 사용한다면 질의함수를 호출하도록 바꾸고, 원래 함수를 호출하는 코드를 아래 추가한다.
- 원래 함수에서 질의함수를 제거한다.
- 중복코드가 많이보인다면, 변경함수에서(원래함수) 질의함수를 사용하도록 고칠수있는지 보자.
11.2 함수 매개변수화하기
- 두 함수의 로직이 비슷하고 리터럴값만 다르다면, 값을 매개변수로 바꾸어 함수를 합치자.
- 비슷한 함수들이 범위를 다룰때에는 중간에 해당하는 함수에서 시작하는것이 좋다.
11.3 플래그 인수 제거하기
- 플래그 인수 : 호출되는 함수가 실행할 로직을 호출하는 쪽에서 선택하기 위해 전달하는 인수.
- 호출하는 함수의 동작과 호출방식등이 직관적이지 않다.
- 하나의 기능만 수행하는 명시적인 함수를 제공하는것이 이상적이다.
- 플래그 인수가 둘 이상이면 함수가 많은일을 처리한다는 신호, 같은 로직을 조합해내는 더 간단한 함수를 만들 방법을 고려해야한다.
- 매개변수를 까다로운 방식으로 사용된다면, 플래그까지 감싸는 래핑함수를 만들고, 리팩토링하면 명확하다.
11.4 객체 통채로 넘기기
- 레코드를 통채로 넘기면 변화에 대응하기 쉽다.
- 함수사용법을 이해하기 쉽다.
- 데이터중 일부를 받는 함수가 여러개일때, 객체 통채로 넘기기 리팩토링을 하면 중복코드를 발견할수있다
- 특정 객체데이터만 사용한다면 객체안으로 메서드를 넣는 리팩토링까지 이어질수있다. 클래스로 추출(7.5)
11.5 매개변수를 질의함수로 바꾸기
- 반대 : 11.6 질의함수를 매개변수로 바꾸기
- 함수가 스스로 쉽게 결정할 수 있는 값을 매개변수로 건네는것도 일종의 중복이다.
- 매개변수를 제거함으로써 함수에 원치않은 의존성이 추가되는경우는 리팩토링하면 안된다.
- 함수가 참조투명해야한다. : 함수에 같은값을 주면 항상 똑같이 동작
- 매개변수의 값을 계산하는 코드를 별도 함수로 추출해둔다.
11.6 질의 함수를 매개변수로 바꾸기
- 참조를 풀어내느 책임을 호출자로 옮길때.
절차
- 변수 추출하길로 질의 코드를 함수 본문의 나머지 코드와 분리한다.
- 함수 본문중 해당 질의를 호출하지 않는 코드들을 별도 함수로 추출한다.
- 1)의 변수를 인라인하여 제거한다.
- 새 함수를 원래함수 호출부로 인라인한다.
- 새함수의 이름을 원래함수의 이름으로 고쳐준다.
11.7 세터 제거하기
- 접근자로만 필드를 다루려할때. 생성자 안에서도 setter를 생성하는 경우.
- 빈 생성자 호출 후 setter로 값을 넣는 초기화방식일때
- 필드를 불변으로 만들어 변경가능성을 줄이자.
11.8 생성자를 팩터리 함수로 바꾸기
- 생성자의 이름은 고정되어있다.
- 자바에서는 해당클래스의 인스턴스만 반환되어야한다. 서브클래스는 불가.
11.9 함수를 명령으로 바꾸기
- 반대 : 11.10 명령을 함수로 바꾸기
- 메서드를 캡슐화하여 command object를 만든다. : 메서드를 요청해 실행하는것이 이 객체의 목적.
- Command Query 할때의 Command 의미가 아님. (이건 이책에서 Modifier라 명명)
- 복잡한 연산을 다룰수있는 메커니즘 제공
- 되돌리기 연산제공가능, 수명주기를 더 정밀하게 제어하는데 필요한 매개변수를 만들어주는 메서드도 제공가능.
- commandObject의 생성자가 메서드의 매개변수를 받게하면, 객체에서 수명주기나 다른 기능을 제공하기 편리해진다.
- 단점 : 단순 메서드호출보다 복잡도가 높아진다.
- command보다 더 간단한 방식으로는 얻을 수 없는 기능이 필요할때만 적용하자.
- 더 나아가 메서드 내 모든 지역변수를 객체의 필드로 전환하자.
11.10 명령을 함수로 바꾸기
- 반대 : 11.9 함수를 명령으로 바꾸기
- 복잡한 추가적인 메커니즘 제공없이 단순 함수하나 호출용이라면 함수 호출이 낫다.
11.11 수정된 값 반환하기
- 값하나를 계산하는 목적이 있는 메서드에서, 데이터가 수정되는 사실을 명확히 알려주기위해 수정된값을 반환하는 메서드를 만들자.
11.12 오류코드를 예외로 바꾸기
- 예외를 사용하면 오류코드를 일일이 검사하거나 오류를 식별해 콜스택 위로 던지는 일을 하지 않아도 된다.
- 예외를 던지는 코드를 프로그램 종료코드로 바꿔도 정상동작한다면 예외를 사용하면 안된다. 오류를 검출하여 프로그램을 정상흐름으로 되돌리게 처리해야한다.
- 발생하는 에러코드가 예상된 것이라면 예외로 바꾸어도 된다. (ex) 메서드 매개변수가 사전조건을 만족한상태로 들어온다고 가정한 경우. 사전조건을 만족하지못하는 경우는 예상된 예외? p.467)
-
절차
- 콜스택 상위에 해당 예외를 처리할 예외 핸들러를 작성.
- 오류코드를 대체할 예외와 그밖의 예외를 구별할 식별방법을 찾는다. (프로그래밍 언어에 맞게 선택하라는뜻)
- 정적검사 수행
- catch절을 수행하여 직접 처리할 수 있는 예외는 적절히 대처하고, 그렇지않으면 throw
- 오류 코드를 반환하는 곳 모두에서 예외를 던지도록 수정
- 오류코드를 콜스택위로 전달하는 코드를 모두 제거.
checked/uncheked Exception 차이..랑은 다른듯 RunTimeException을 던지는 코드를 Exception으로 바꿔도 정상동작한다면 RunTimeException을 사용하면 안된다? -> X
11.13 예외를 사전확인으로 바꾸기
- 함수 수행시 문제가 될 수 있는 조건을 호출전에 검사할 수 있다면 조건을 검사하도록 하자.
- 예외는 뜻밖의 오류, 남용되면 안된다.