프로그램을 개발하다 보면 우리는 외부의 코드를 우리의 코드에 통합해야 할 일이 많이 생긴다.
이번 장은 이 소프트웨어의 경계를 깔끔하게 처리하는 방법에 대해 다룬다.
외부 코드 사용하기
예를 들어 Map 을 만들어 여기저기 뿌린다고 생각해보자.
java.util.Map 이 제공하는 메서드 중에는 clear() 이 있다.
Map 을 받아 이용하는 클라이언트 중 누군가 clear() 를 실행해버리면 큰일이 날 것이다.
또는 Map에 특정 자료형만 저장하기로 약속했다고 하자.
하지만 누군가가 add() 를 통해 다른 객체 유형을 넣지 않을 것이란 보장이 있는가?
두번쨰 문제점은 제네릭스를 이용하면 해결되지만 첫번째 문제점을 해결해 주지는 않는다.
이 문제에 대하여 해결책은,
다른 사람들이 쓸 이 경계 Map 을 객체로 포장하는 것이다.
책의 예시를 보자.
public class Sensors {
priavet Map sensors = new HashMap();
public Sensor getById() {
return (Sensor) sensors.get(id);
}
}
경계 인터페이스 Map을 객체로 포장하여 숨겼다. 그리고 Map이 아닌 Sensors를 사용한다.
이제는 클라이언트가 Map 에 어떤 객체를 포함하는지 신경쓰지 않아도 된다.
이제는 클라이언트가 clear() 같은 메소드를 사용하지 않을 것이라는 것을 안다.
Sensors 클래스 안에서 규칙을 정의하고 따르도록 만들면 된다.
이와 관련하여 일급 컬렉션이라는 개념도 있다.
경계 인터페이스에서 Map 과 같은 것들을 공개 API의 인수나 반환값으로 넘겨 예상외의 행동이 일어나는일이 있으면 안된다.
학습 테스트
외부 라이브러리는 익히는 데에는
우리쪽 코드를 작성하여 간단한 테스트 케이스를 작성해 외부 코드를 익히는 것이 좋다.
외부코드 log4j 를 테스트하는 코드가 책에 소개되어 있다.
Intellij 의 순수 자바 프로젝트에서 Log4j 를 사용해보려 노력했지만,, 실패했다.
다음에 Spring 사용할 기회가 되면 해봐야 겠다.
중요한 점은, 외부 라이브러리를 간단한 테스트를 작성하며 익히면 좋다는 것이다.
깔끔한 경계로 분리하기
- 어댑터 패턴을 이용하여 우리에 맞는 인터페이스로 조절하기
- Map 같은 경계 인터페이스를 객체로 감싸서 우리가 원하는 기능만 정의하여 원치않는 기능을 방지하기
- 방어적 복사를 하는 방법도 하나의 방법이 될 수 있다.