Chapter 8 - Boundaries
in Booknotes / Clean Code
자료를 세세하게 공개하기보다는 추상적인 개념으로 표현해야 한다
- 외부 코드 (오픈소스, 다른팀의 컴포)를 우리 코드에 깔끔하게 통합해야 함
- 소프트웨어 경계를 깔끔하게 처리하는 기법/기교
외부 코드 사용하기
- 피키지/프레임워크 제공자: 적용성 최대한 넓히기 (더 많은 환경 제공 \(\rightarrow\) 더 많은 구매자)
- 사용자: 자신의 요구에 집중하는 인터페이스 요구
\(\Rightarrow\) 시스템 경계 문제 생길 소지 많음
- 예시: Java의
Map
메소드 (굉장히 많음)- 여기저기 넘겨질 시 다른 곳에서 Map
clear()
도 가능함!
- 여기저기 넘겨질 시 다른 곳에서 Map
- Map이 반환하는 Object를 올바른 유형으로 변환하는 것은 클라이언트 책임
Map sensors = new HashMap(); Sensor s = (Sensor)sensors.get(sensorId);
- 깨끗하지 않으며, 의도를 명확히 알기 어려움
- Generics 사용한 코드: 가독성은 올리나 여전히 사용자에게 필요없는 기능까지 제공
Map<String, Sensor> sensors = new HashMap<Sensor>(); Sensor s = sensors.get(sensorId);
- BEST: 경계 인터페이스인 Map을
Sensors
안으로 숨긴다public class Sensors { private Map sensors = new HashMap(); public Sensor getById(String id){ return (Sensor) sensros.get(id); } } // 이하 생략
- Map interface가 변하더라도 나머지 프로그램에는 영향을 미치지 않는다! Generics 사용 여부 또한 문제 X (안에서 결정)
- 필요한 인터페이스만 제공 (이해쉽고 오용 어려움)
- “Map 클래스를 사용할 때마다 위와 같이 캡슐화하라는 소리가 아니다. Map을 (혹은 유사한 경계 인터페이스를) 여기저기 넘기지 말라는 말이다”
- 이용하는 클래스 밖으로 노출되지 않도록 주의한다
- Map의 인스턴스를 공개 API의 인수로 넘기거나 반환값으로 사용하지 않는다
경계 살피고 익히기
외부 라이브러리 사용 시
학습 테스트 진행- 주로 외부 문서 정독 -> 사용 -> 버그 발견 시 우리 문제인지 외부 라이브러리 문제인지 오랫동안 고민
- 해결: 먼저 타사 라이브러리 테스트 (간단한 테케 작성)
- API 를 사용하려는 목적에 초점을 맞춤
- 모든 지식을 한 클래스로 캡슐화하면 나머지 프로그램은 경계 인터페이스를 몰라도 된다 (사용, 유지보수 편리)
학습 테스트는 공짜 이상이다
- 드는 비용이 없으며 (어차피 API를 배워야 하므로) 오히려 필요한 지식만 확보하는 방법
- 투자하는 노력보다 얻는 성과가 크다
- 패키지 업데이트 시 학습 테스트를 돌려 차이가 있는지 확인할 수 있다. (모든 업데이트가 우리 코드와 호환 보장 X )
- 새 버전으로 이전 쉬움
아직 존재하지 않는 코드를 사용하기
- 인터페이스마저 정의 안된 코드를 사용해야 하는 경우
- 먼저 바라는 인터페이스를 구현
- 전적으로 통제 가능
- 가독성 높아지며 의도 명확해짐
- Adpater을 구현해 실제 제공해주는 API의 인터페이스와 우리의 인터페이스의 간극을 메움
- API 사용을 캡슐화해 API가 바뀔 때 수정할 코드를 한 곳으로 모음
이번 장은 매우 어려웠다…100% 이해는 못한느낌. 추후에 완전히 이해하는 날이 올 것이라고 기대한다. 경계 인터페이스를 관리하는 방법이 흥미롭다. 현재 여러 외부 라이브러리를 프로젝트에 도입하고 있는데 이 방법을 사용해봐야 하나 싶다. 이렇게까지 장기적으로 코드의 가독성 및 유지보수성을 생각해 본 적이 없는듯 하다.