Be-Developer

Refactoring 11


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)

절차

  1. 대상 함수를 복제하고 질의 목적에 충실한 이름을 짓는다.
  2. 새 질의함수에서 부수효과를 모두 제거한다.
  3. 정적 검사를 수행한다.
  4. 원래 함수를 수행하는곳에서 반환값을 사용한다면 질의함수를 호출하도록 바꾸고, 원래 함수를 호출하는 코드를 아래 추가한다.
  5. 원래 함수에서 질의함수를 제거한다.
    1. 중복코드가 많이보인다면, 변경함수에서(원래함수) 질의함수를 사용하도록 고칠수있는지 보자.

11.2 함수 매개변수화하기

  • 두 함수의 로직이 비슷하고 리터럴값만 다르다면, 값을 매개변수로 바꾸어 함수를 합치자.
  • 비슷한 함수들이 범위를 다룰때에는 중간에 해당하는 함수에서 시작하는것이 좋다.

    11.3 플래그 인수 제거하기

  • 플래그 인수 : 호출되는 함수가 실행할 로직을 호출하는 쪽에서 선택하기 위해 전달하는 인수.
    • 호출하는 함수의 동작과 호출방식등이 직관적이지 않다.
    • 하나의 기능만 수행하는 명시적인 함수를 제공하는것이 이상적이다.
  • 플래그 인수가 둘 이상이면 함수가 많은일을 처리한다는 신호, 같은 로직을 조합해내는 더 간단한 함수를 만들 방법을 고려해야한다.
  • 매개변수를 까다로운 방식으로 사용된다면, 플래그까지 감싸는 래핑함수를 만들고, 리팩토링하면 명확하다.

11.4 객체 통채로 넘기기

  • 레코드를 통채로 넘기면 변화에 대응하기 쉽다.
  • 함수사용법을 이해하기 쉽다.
  • 데이터중 일부를 받는 함수가 여러개일때, 객체 통채로 넘기기 리팩토링을 하면 중복코드를 발견할수있다
  • 특정 객체데이터만 사용한다면 객체안으로 메서드를 넣는 리팩토링까지 이어질수있다. 클래스로 추출(7.5)

11.5 매개변수를 질의함수로 바꾸기

  • 반대 : 11.6 질의함수를 매개변수로 바꾸기
  • 함수가 스스로 쉽게 결정할 수 있는 값을 매개변수로 건네는것도 일종의 중복이다.
  • 매개변수를 제거함으로써 함수에 원치않은 의존성이 추가되는경우는 리팩토링하면 안된다.
  • 함수가 참조투명해야한다. : 함수에 같은값을 주면 항상 똑같이 동작
  • 매개변수의 값을 계산하는 코드를 별도 함수로 추출해둔다.

11.6 질의 함수를 매개변수로 바꾸기

  • 참조를 풀어내느 책임을 호출자로 옮길때.

    절차

    1. 변수 추출하길로 질의 코드를 함수 본문의 나머지 코드와 분리한다.
    2. 함수 본문중 해당 질의를 호출하지 않는 코드들을 별도 함수로 추출한다.
    3. 1)의 변수를 인라인하여 제거한다.
    4. 새 함수를 원래함수 호출부로 인라인한다.
    5. 새함수의 이름을 원래함수의 이름으로 고쳐준다.

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)
  • 절차

    1. 콜스택 상위에 해당 예외를 처리할 예외 핸들러를 작성.
    2. 오류코드를 대체할 예외와 그밖의 예외를 구별할 식별방법을 찾는다. (프로그래밍 언어에 맞게 선택하라는뜻)
    3. 정적검사 수행
    4. catch절을 수행하여 직접 처리할 수 있는 예외는 적절히 대처하고, 그렇지않으면 throw
    5. 오류 코드를 반환하는 곳 모두에서 예외를 던지도록 수정
    6. 오류코드를 콜스택위로 전달하는 코드를 모두 제거.

checked/uncheked Exception 차이..랑은 다른듯 RunTimeException을 던지는 코드를 Exception으로 바꿔도 정상동작한다면 RunTimeException을 사용하면 안된다? -> X

11.13 예외를 사전확인으로 바꾸기

  • 함수 수행시 문제가 될 수 있는 조건을 호출전에 검사할 수 있다면 조건을 검사하도록 하자.
  • 예외는 뜻밖의 오류, 남용되면 안된다.