시스템에 들어가는 모든 소프트웨어를 직접 개발하는 경우는 드물다. 때로는 사내 다른 팀이 제공하는 컴포넌트를 사용한다.
이 장에서 이러한 외부 코드(Third-Party Code)를 우리 코드에 깔끔하게 통합할 수 있도록, 소프트웨어 경계(Software Boundaries)를 깔끔하게 처리하는 기법을 살펴본다.
외부코드를 사용하는 것
인터페이스 제공자-사용자 간에는 특유의 텐션이 있다. 이런 텐션으로 시스템 경계에서 문제가 생길 소지가 많다.
- 인터페이스 제공자
- 적용성을 최대한 넓히려 애쓴다. 더 많은 환경에서 돌아가야 더 많은 고객이 구매하니까.
- 다양한 인터페이스로 수많은 기능을 제공한다. 유용하지만 그만큼 위험도 크다.
- 사용자가 필요하지 않은 기능까지 제공한다.
- 인터페이스 사용자
- 자신의 요구에 집중하는 인터페이스를 바란다.
경계 인터페이스를 클래스 안으로 숨기고, 그 안에서 객체 유형을 관리하고 변환하도록 하자. 그렇게 하면 외부코드 인터페이스가 변하더라도 나머지 프로그램에 영향을 미치지 않게된다. 또한 프로그램에 필요한 인터페이스만 제공해서 오용하기 어렵게 된다.
(외부 인터페이스를 사용할 때마다 캡슐화하라는 소리가 아니다.)
학습 테스트, 드는 비용은 없고 성과는 크다.
외부 API 문서를 자세히 읽기 전, 간단한 테스트 코드 작성을 통해 외부 코드를 익히는 방법도 있다. API를 사용하는데 초점을 맞춰서 프로그램에서 사용하려는 방식대로 외부 API를 호출해보는 것이다. 것이다.
짐 뉴커크(Jim Newkirk)는 이를 학습 테스트(Learning Tests)라고 불렀다. 어쨌든 API를 익혀야 하니까 학습 테스트에 드는 비용은 거의 없다.
학습 테스트 중 얻은 모든 지식을 바탕으로 클래스에 외부 API를 캡슐화해둔다. 이렇게 하면 프로그램의 나머지 부분에서는 외부 API의 경계 인터페이스를 몰라도 된다. 또, 우리 버그인지 라이브러리 버그인지 찾아내느라 오랜 디버깅으로 골치를 앓는 일이 줄어들 것이다.
외부코드를 통합했다고 하더라도 항상 우리 코드와 호환되리라는 보장은 없다. 외부코드의 새 버전이 나올 때마다 새로운 위험이 생긴다. 이 때 학습 테스트를 돌려 차이가 있는지 확인할 수 있다. 학습 테스트가 패키지가 예상대로 동작하는지 검증하는 수단이 되는 것이다. 이러한 테스트가 없다면 버전을 올리기 두려운 나머지 오래된 버전을 필요 이상으로 오래 사용하는 상황에 처할 수 있다.
아직 존재하지 않는 코드 사용하기
제공받을 API의 설계가 결정되지 않은 상황에 개발을 진행해야할 수도 있다. 이런 상황에서는 요구사항을 분석해 자체적으로 인터페이스를 정의해둘 수 있다.
API를 제공받은 이후에는 어댑터 패턴으로 API 사용을 캡슐화해서 API가 바뀔 때 수정할 코드를 한곳으로 모을 수 있다.
깨끗한 경계
경계에 위치하는 코드는 깔끔히 분리하는 것이 좋다. 외부 패키지를 호출하는 코드를 가능한 줄여 경계를 관리하자. 통제할 수 없는 외부 패키지에 의존하는 대신, 통제 가능한 우리 코드에 의존하는 편이 훨씬 좋기 때문이다.
새로운 클래스로 경계를 감싸거나, 패키지로부터 제공받는 인터페이스를 어댑터 패턴을 적용해 우리가 원하는 인터페이스로 변환하자. 이는 코드 가독성과 일관성을 올릴 수 있는 방법이기도 하다.
출처: 도서 클린코드 애자일 소프트웨어 장인 정신, 로버트 C.마틴 지음 | 박재호, 이해영
'General' 카테고리의 다른 글
[클린 코드] 10장 클래스 (0) | 2023.06.04 |
---|---|
[클린 코드] 9장 단위 테스트 (0) | 2023.05.28 |
[클린 코드] 7장 오류 처리 (0) | 2023.05.25 |
[클린 코드] 6장 객체 vs 데이터구조 (0) | 2023.05.20 |
[클린 코드] 5장 포맷 맞추기 (1) | 2023.05.18 |