경계

시스템에 들어가는 모든 SW를 개발하기는 드물다.
때로는 패키지를 사고, 때로는 오픈 소스를 사용한다. 또는 사내 다른 팀의 컴포넌트를 이용하기도 한다.

외부 코드 사용하기

인터페이스 제공자와 사용자 사이에는 긴장이 존재한다.
제공자는 적용성을 최대한 넓히려 애쓴다. -> 커버리지가 커야 많은 사용자가 구매하니까
반대로 사용자는 자신의 요구에 집중하는 인터페이스를 바란다.

하나의 예로 java.util.Map 에는 clear() 메소드가 존재한다.
Map을 이리저리로 옮기면서 clear()라는 메소드를 누구나, 어디서든 호출할 수 있다.

ex) 센서를 담는 Map을 생성하자

Map sensors = new HashMap();
Sensor s = (Sensor)sensors.get(sensorId);

해당 맵에는 어떤 객체라도 들어갈 수 있다.

-> 제네릭을 사용해보자

Map<String, Sensor> sensors = new HsahMap<Sensor>();
Sensor s = sensors.get(sensorId);

하지만 Map의 기본 API인 clear()와 같은 기능은 제어하지 못한다. (즉, 여전히 누구나 사용할 수 있다.)

-> 다른 방법을 사용해보자

public class Sensors{
    private Map sensors = new HashMap();

    public Sensor getById(String id){
        return (Sensor) sensors.get(id);
    }
    ...
}

제네릭을 사용하지 않더라도 사용하는 입장에서는 문제가 되지 않는다.
또한 필요한 API만 사용자에게 제공이 가능하다.(clear()와 같은 불필요한 API는 제공하지 않아도 된다.)
Map을 사용할 때마다 캡슐화하라는 소리가 아니다. Map을 여기저기 넘기지 말라는 말이다.

경계 살피고 익히기

외부 코드를 사용하면 적은 시간에 많은 기능을 출시하기 쉬워진다.
외부 패키지 테스트가 우리의 책임은 아니다. 하지만 우리가 사용할 코드를 테스트하는 것은 우리의 책임이다.

  1. 외부 라이브러리를 가져온다.
  2. 며칠 문서를 보며 사용법을 익힌다.
  3. 우리쪽 코드를 작성해 라이브러리를 검증한다.
  4. 우리 버그인지 라이브러리 버그인지 찾아내느라 시간이 정말 많이 걸린다.

이처럼 외부 코드를 익히기는 어렵다. 통합하기도 어렵다.
그렇다면 우리쪽 코드를 작성해 외부 코드를 호출하는 대신 간단한 테스트 케이스를 작성하며 익히는 것은 어떤가?
-> 이를 학습 테스트라 부른다.

깨끗한 경계

경계에서는 흥미로운 일이 많이 벌어진다.
변경이 대표적인 예다.
SW 설계가 우수하다면 변경하는데 많은 투자와 재작업이 필요하지 않다.
통제가 불가능한 외부 패키지에 의존하는 대신 통제가 가능한 우리 코드에 의지하는 편이 훨씬 좋다.

외부 패키지를 호출하는 코드를 가능한 줄여 경계를 관리하자.
Map에서 봤듯이, 새로운 클래스로 경계를 감싸거나, ADAPTER 패턴을 사용해 우리가 원하는 인터페이스를 패키지가 제공하는 인터페이스로 변환하자.

+ Recent posts