경계

  • 소프트웨어를 개발하기 위해 사용하는 외부 패키지, 오픈소스 등을 어떻게 깔끔하게 통합해야함

외부 코드 사용하기

  • 외부 패키지 제공자는 보다 넓은 적용범위를 제공하려고하고 외부 패키지 사용자는 자신의 요구에 보다 집중하는 인터페이스를 원함
  • 예로 Map은 굉장히 많은 기능을 제공하는 인터페이스
  • Map에는 clear라는 원소 비우기 기능이 존재함, 구현체 제공자가 사용자에게 제공하고 싶지 않을 수 있지만 clear는 실행가능함
  • 다음과 같은 코드를 사용하면 Map에 어떠한 객체든 담을 수 있음
Map sensors = new HashMap();
Sensor s = (Sensor)sensors.get(sensorId);
  • 제네릭을 사용하면 코드 가독성이 크게 높아짐
Map<String, Sensor> sensors = new HashMap<Sensor>();
Sensor s = sensors.get(sensorId);
  • 그러나 위예도 사용자에게 제공하고 싶지않은 기능들을 제공해야함
  • 다음과 같이 감싸는 클래스를 제공하여 제공 기능 결정함
  • 이때 제네릭 사용여부는 해당 클래스가 결정해야함
public class Sensors {
  private Map sensors = new HashMap();
  public Sensor getById(String id) {
    return (Sensor) sensor.get(id);
  }
}
  • 경계 인터페이스인 Map을 Sensors안으로 숨김
  • 이는 Map을 사용할때마다 위와 같은 클래스를 정의하라는 소리가 아님
  • Map을 여기저기 넘기지 말라는 의미임
    • Map을 공개 api의 인수로 넘기거나 반환값으로 사용하지 않는 것이 포인트

경계 살피고 익히기

  • 곧바로 우리쪽 코드를 작성해 외부 코드를 호출하는 대신 먼저 간단한 테스트 케이스를 작성해 외부코드를 학습
  • 짐 뉴커크는 이를 학습테스트라고 함
    • 학습 테스트는 프로그램에서 사용하려는 방식으로 외부 API를 호출
    • 즉 통제된 환경에서 API를 제대로 이해하는지 확인하느 것

log4j 익히기

  • 로깅 기능을 직접 구현하는 대신 log4j를 사용한다고 가정
  • 테스트코드에서 log4j를 사용하면서 학습해나감

학습 테스트는 코드이상이다

  • 학습테스트는 필요한 지식만 확보하는 손쉬운 방법
  • 이해도를 높여주는 정확한 실험
  • 투자하는 노력보다 얻는 성과가 더 큼
  • 새로운 버전의 패키지가 배포되더라도 테스트를 통해 호환성을 체크
    • 즉 새로운 버전의 패키지 도입이 쉬워짐

아직 존재하지 않는 코드를 사용하기

  • 경계관련 또 다른 유형은 아는 코드와 모르는 코드를 분리하는 것
  • 이를 위해 ADAPTER 패턴을 사용
    • 하나의 인터페이스에대한 테스트 기능의 클래스와 실제 기능을 클래스를 사용

깨끗한 경계

  • 소프트웨어 설계가 우수하다면 변경하는데 많은 투자와 재작업이 필요없음
  • 외부 패키지를 호출하는 코드를 가능한 줄여 경계를 관리해야함
    • Map에서 봤듯이 새로운 클래스로 경계를 감싸거나 ADAPTER 패턴을 사용해 우리가 원하는 인터페이스를 패키디가 제공하는 인터페이스로 변경하여 사용
  • 이는 코드 가독성, 경계 인터페이스를 사용하는 일관성, 외부 패키지 변경시 변경할 코드가 줄어드는 장점이 존재