[클린코드] 8장 : 경계

목록으로 돌아가기

이번에 다룰 경계는 개발자가 직접 짠 코드와 외부에서 가져오는 코드 사이의 호출 로직 상 부분이다.

나아가 아는 코드와 모르는 코드를 분리하는 부분도 다룰 예정이다.

  • 외부 코드와 개발자 코드 사이의 경계
    • 외부 코드는 범용성 및 적용성을 생각해 최대한 많은 케이스에 대응하여 코드를 작성한다.
    • 내부(개발자) 코드는 자체 앱에 집중 대응하여 코드를 작성한다.
    • 경계 인터페이스를 사용한다면 이를 여기저기에서 작성하는 것을 지양하자. 나아가 많이 쓰인다면, 클래스 등에 넣어서 사용하는 것이 좋다.
      • 이 때, 클래스에 넣었다면 클래스 밖에 노출되지 않도록 주의해야한다. 공개 API 인수로 넘기는 등을 주의해야한다.
    • 외부 코드를 사용하기 전, 원하는 기능이 모두 동작하는지 먼저 확인하자. 공식 문서 등을 활용하면 좋다.

  • 학습 테스트
    • 테스트 케이스를 작성하여 외부 코드를 우리 목적에 맞게 동작하는지 확인하자. 이를 통해 추후 외부 모듈이 업데이트 된다고 해도 잘 동작하는지 파악하기 쉬워진다.
    • 학습 테스트는 이해도를 손쉽게 높혀준다.
    • 이를 통해 검증 및 학습, 유지보수를 용이하게 가져갈 수 있다.
    • 경계를 테스트하는 학습 테스트가 있다면 패키지를 새 버전으로 올리는 것이 무섭지 않을 것이다.

  • 아는 코드와 모르는 코드 사이의 경계
    • 아직 만들어지지 않은 코드를 사용한다.
    • 개발자 입장에서 먼저 요구하고자하는(만들어지길 바라는) 스펙의 인터페이스를 자체적으로 정의한다.
    • 이후 어뎁터 패턴을 사용하여 구현.
      • 어뎁터 패턴은 인터페이스와 인터페이스 간 변환해주는 패턴이다.
      • implements를 사용하여 클레스에 인터페이스를 삽입한다.
      • 어뎁터 코드에 implement된 인터페이스 및 변환하고자하는 인터페이스를 코드로 삽입하여 변환을 작업한다.
    • 모르는 코드 사용을 캡슐화해 모르는 코드가 바뀔 때마다 수정할 코드를 한 곳으로 모음

⇒ 위의 학습을 통해 깨끗한 경계를 만들 수 있다. 테스트 케이스 작성 및 어뎁터 패턴을 사용하여 통제 불가능한 외부 코드보다 통제 가능한 우리 코드에 집중 및 의존하도록 하자.

본문에 대한 예시

외부 코드와 개발자 코드 사이의 경계를 확인할 수 있다. 다음 코드는 리액트 달력을 불러와 우리가 원하는 달력으로 보여주는 함수다.

function Calendar({ initialText, returnValue }: CalendarProps) {
  const [selectedDate, setSelectedDate] = useState("")

  // 수정 화면에서 넘어온 날짜 정의
  useEffect(() => {
    if (initialText) {
      setSelectedDate(moment(initialText).format("YYYY-MM-DD"))
    }
  }, [initialText])

  // 날짜가 클릭되었을 시 선택된 날짜 설정 및 값 리턴
  const onChange = (selectedDate: Date) => {
    setSelectedDate(moment(selectedDate).format("YYYY-MM-DD"))
    returnValue(moment(selectedDate).format("YYYY-MM-DD"))
  }

  return (
    <>
      <h3>{"날짜를 선택해주세요."}</h3>
      <ReactCalendar
        className="react-calendar"
        value={selectedDate ? new Date(selectedDate) : null}
        onChange={(parameter: Date) => onChange(parameter)}
      />
      <h3>{"선택된 날짜: " + selectedDate}</h3>
    </>
  )
}

이를 보면 첫 번째로, 여러 케이스에 대응하여 범용성을 높인 리액트 달력 모듈을 사용하여, 개발자 앱에 집중한 다른 달력 함수를 만든 것을 볼 수 있다. 개발자가 사용하기 위하여 initialText, returnValue의 두 매개변수를 부여하였고, 앱에 최적화하여 변수를 입력받는다. 또한, onChange 함수를 작성하여 개발자가 원하는 동작을 하게끔 강제한 것을 볼 수 있다.

기존 리액트 달력의 onChange는 날짜 매개변수를 출력하는 반면, 개발자는 출력된 날짜 매개변수를 이용하여 상태 값을 변경하거나 부모 컴포넌트에게 콜백을 해주는 기능을 볼 수 있다. 이는 오로지 현재 앱을 위한 것이므로, ‘외부 코드와 개발자 코드 사이의 경계’에서 외부 코드는 범용성을 생각하며 개발자 코드는 앱에 집중한다는 것에 대한 예시로 충분하다.

학습 테스트의 경우에는 실제 외부 모듈은 아니지만, 한 함수로 간단하게 예시를 들어보고자 한다.

export const isEmpty = (object: any) => {
  return !Object.keys(object).length
}

만약 위와 같은 외부 모듈이 있다고 가정해보자. 개발자는 내부 코드를 모르는 상태에서 학습 테스트를 하기 위해 다음과 같은 노력을 할 수 있다.

  1. 매개변수로 object 및 object가 아닌 것을 넣어보기
  2. 해당 함수를 로그로 찍어 출력 확인하기
  3. 해당 함수를 새 변수 및 상수로 지정해주어 로그로 출력 확인하기

등등 여러 방법을 시도함으로써 해당 함수의 사용법을 익힐 수 있다.

오늘은 외부/내부 코드 및 모르는/아는 코드 의 경계에 대해 알아보았다. 또한 외부 및 모르는 코드를 사용하기 위해서 시행할 수 있는 테스트 기법도 학습하였다. 코드를 작성하다보면 수많은 외부 모듈들을 사용해야한다. 이 때, 이들의 특성을 알고 개발자만의 코드로 사용하기 위해서 오늘 배운 경계를 다루는 방법을 사용하여 더욱 앱 개발에 최적화된 코드 작성을 기대한다.

author-profile
Written by 상 한규

댓글