[리팩터링 2판] 11. API 리팩터링

API를 이해하기 쉽고 사용하기 쉽게 만드는 일은 중요한 동시에 어렵기도 하다.
그래서 API를 개선하는 방법을 새로 깨달을 떄마다 그에 맞게 리팩터링해야 한다.


11.1. 질의 함수와 변경 함수 분리하기

배경

  • 우리는 외부에서 관찰할 수 있는 겉보기 부수효과(observable side effect)가 전혀 없이 값을 반환해주는 함수를 추구해야 한다.
  • 겉보기 부수효과가 있는 함수와 없는 함수는 명확히 구분하는 것이 좋다.
  • 질의 함수(읽기 함수)는 모두 부수효과가 없어야 한다.
    • 명령-질의 분리
  • 값을 반환하면서 부수효과도 있는 함수를 발견하면 상태를 변경하는 부분과 질의 하는 부분을 분리하려 시도한다. 무조건이다!


11.2. 함수 매개변수화하기

배경

  • 두 함수로직이 아주 비슷하고 단지 리터럴 값만 다를 때, 그 다른 값만 매개변수로 받아 처리하는 함수 하나로 합쳐서 중복을 없앨 수 있다.


11.3. 플래그 인수 제거하기

배경

  • 내가 플래그 인수를 싫어하는 이유가 있다.

    • 호출할 수 있는 함수들이 무엇이고 어떻게 호출해야 하는지를 이해하기 어려워지기 때문이다.

    • 특정 기능 하나만 수행하는 명시적인 함수를 제공하는 편이 훨씬 깔끔하다.

      bookConcert(aCustomer, "preiminum");	// 플래그 함수 사용
      priminumBookConcert(aCustomer);			// 명시적 함수로 변환
      
  • 함수 하나에서 플래그 인수를 두 개 이상 사용하면 플래그 인수를 써야하는 합당한 근거가 될 수 있다.

    • 그런데 다른 관점에서 보자면, 플래그 인수가 둘 이상이면 함수 하나가 너무 많은 일을 처리하고 있다는 신호이기도 하다.


11.4. 객체 통째로 넘기기

배경

  • 레코드를 통째로 넘기면 변화에 대응하기 쉽다.
  • 함수가 레코드 자체에 의존하기를 원치 않을 때는 이 리팩터링을 수행하지 않는다.
  • 많은 사람이 놓치는 사례가 하나 더 있다. 다른 객체의 매서드를 호출하면서 호출하는 객체 자신이 가지고 있는 데이터 여러 개를 건네는 경우다.
    • 이런 상황이면 데이터 여러 개 대신 객체 자신의 참조만 건네도록 수정할 수 있다.\


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

배경

  • 매개변수가 있다면 결정 주체가 호출자가 되고, 매개변수가 없다면 피호출 함수가 된다.
  • 나는 습관적으로 호출하는 쪽을 간소하게 만든다.
    • 책임 소재를 피호출 함수로 옮긴다.
  • 제거하려는 매개변수의 값을 다른 매개변수에 질의해서 얻을 수 있다면 안심하고 질의 함수로 바꿀 수 있다.
  • 대상 함수는 참조 투명(referential transperency)해야한다.
    • 참조 투명이란 함수에 똑같은 값을 건네 호출하면 항상 똑같이 동작한다는 뜻이다.


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

배경

  • 함수 안에 두기엔 거북한 참조를 발견할 때가 있다. (전역 변수를 참조한다거나…)
  • 참조 투명하지 않은 원소에 접근하는 모든 함수는 참조 투명성을 잃게 되는데, 이 문제는 해당 원소를 매개변수로 바꾸면 해결된다.
  • 질의 함수를 매개변수로 바꾸면 어떤 값을 제공할지를 호출자가 알아내야 한다.


11.7. 세터 제거하기

배경

  • 세터 제거하기 리팩터링이 필요한 상황은 주로 두가지다.
  • 첫 번째, 오직 생성자에서만 세터를 호출할 때
    • 나라면 세터를 제거해서 객체가 생성된 후에는 값이 바뀌면 안 된다는 뜻을 분명히 할 것이다.
  • 두 번째, 클라이언트에서 생성 스크립트를 사용해 객체를 생성할 때
    • 설계자는 스크립트가 완료된 뒤로는 그 객체의 필드 일부 혹은 전체가 변경되지 않으리라 기대한다.


11.8. 생성자를 팩터리 함수로 바꾸기

배경

  • 생성자는 객체를 초기화하는 특별한 용도의 함수다.
  • 기본 이름보다 더 적절한 이름이 있어도 사용할 수 없다.
  • 하지만 팩터리 함수는 이런 제약이 없다. 팩터리 함수로 생성자를 감싸보자.


11.9. 함수를 명령으로 바꾸기

배경

  • 함수를 그 함수만을 위한 객체 안으로 캡슐화하면 더 유용해지는 상황이 있다.
    • 이런 객체를 명령 객체 혹은 명령(command)이라 한다.
  • 명령은 평범한 함수 매커니즘보다 훨씬 유연하게 함수를 제어하고 표현할 수 있다.


11.10. 명령을 함수로 바꾸기

배경

  • 명령 객체는 복잡한 연산을 다룰 수 있는 강력한 매커니즘을 제공한다.
  • 하지만 로직이 크게 복잡하지 않다면 명령 객체는 장점보다 단점이 크니 평범한 함수로 바꿔주는 게 낫다.


11.11. 수정된 값 반환하기

배경

  • 데이터가 어떻게 수정되는지를 추적하는 일은 코드에서 이해하기 가장 어려운 부분 중 하나다.
  • 데이터가 수정된다면 그 사실을 명확히 알려주는게 대단히 중요하다.
  • 변수를 갱신하는 함수라면 수정된 값을 반환하는 것이 좋다.


11.12. 오류 코드를 예외로 바꾸기

배경

  • 예외는 프로그래밍 언어에서 제공하는 독립적인 오류 처리 매커니즘이다.
  • 예외는 정확히 예상 밖의 동작일 때만 쓰여야 한다.


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

배경

  • 함수 수행시 문제가 될 수 있는 조건을 호출 전에 검사할 수 있다면, 예외를 던지는 대신 호출하는 곳에서 조건을 검사하도록 해야 한다.

댓글남기기