Angular 프로젝트를 진행하면서 Google Maps API를 활용해 다양한 지도 기능을 구현하는 작업이 있었습니다.
하지만 초기에 API 객체를 직접 사용하는 방식으로 진행하다 보니 점점 유지보수와 확장성에 문제가 생기기 시작했습니다.
이를 해결하기 위해 어댑터 패턴(Adaptor Pattern) 을 적용했고, 이를 통해 얻은 경험을 공유합니다.
1. 문제 인식
처음에는 Google Maps API가 제공하는 객체(Marker, Poligon, Polyline 등)들을 프로젝트 곳곳에서 직접 사용했습니다.
그 당시에는 빠르게 개발할 수 있었지만 시간이 지날수록 다음과 같은 문제들이 보이기 눈에 시작했습니다.
문제 코드(e.g. 마커를 생성하는 코드): google.maps.Marker와 같은 특정 API의 클래스를 사용합니다.
- 높은 의존성
- 코드 곳곳에 Google Maps의 구체적인 타입에 강하게 의존하고 있었습니다.
- 만약 지도 라이브러리를 다른 것으로 교체하거나, Google Maps API 버전이 변경될 경우 수정해야하는 코드가 너무 많아질 위험이 있습니다.
- 유지보수의 어려움
- 버그를 발생시키거나 수정 비용을 크게 증가시키는 문제로 이어졌습니다.
- 유연성 부족
- 프로젝트 요구사항이 변화하거나 다양한 지도 서비스 지원이 필요할 때 빠르게 대응할 수 없는 구조였습니다.
이러한 문제를 해결하기 위해 중간에 어댑터 계층을 도입하는 것이 필요하다고 판단했습니다.
2. 해결 방법
어댑터 패턴 도입
- Google Maps API 객체들을 그대로 사용하는 대신 프로젝트 내부에 별도의 클래스를 만들어 Google Maps 객체를 감싸는 방식으로 개선했습니다.
- 구현한 클래스 및 인터페이스는 아래와 같습니다.

구조 설계 포인트
- Google Maps 객체를 직접 사용하지 않고 항상 MapPoint, MapBounds, MapSize, MapMarker 클래스를 사용하도록 개선했습니다.
- 각 어댑터 클래스는 Google Maps 객체를
extends 하여 기본 기능은 유지하면서 프로젝트 내 타입 일관성을 확보했습니다.
- 추후 다른 지도 라이브러리로 전환이 필요할 경우 이 어댑터 클래스들만 수정하면 프로젝트 전반의 코드를 수정할 필요가 없습니다.
적용 예시

3. 적용 결과
어댑터 패턴을 적용한 이후 다음과 같은 효과를 얻을 수 있었습니다.
유지보수성 향상
- 지도 관련 기능을 수정하거나 추가할 때 어댑터 클래스를 기준으로 작업할 수 있어 수정 범위가 크게 줄어들었습니다.
- Google Maps API가 버전 업데이트되거나 다른 라이브러리로 교체하더라도 어댑터 계층만 수정하면 되어 훨씬 효율적이었습니다.
타입 안정성 확보
- 모든 지도 객체 타입을 통일된 이름으로 관리할 수 있어서 프로젝트 전체의 코드 일관성과 가독성이 좋아졌습니다.
- 타입스크립트의 타입 체크 기능 덕분에 실수도 크게 줄일 수 있었습니다.
확장성 강화
- 향후 필요 시 OpenLayers나 Leaflet과 같은 다른 지도 라이브러리로도 비교적 쉽게 전환할 수 있는 구조가 완성되었습니다.
4. 느낀 점 및 개선할 점
이번에 어댑터 패턴을 적용하면서 얻은 가장 큰 교훈은
"외부 라이브러리에 직접 의존하지 않고 추상화 계층을 둬야 유지보수와 확장성에서 강력한 이점을 얻을 수 있다"는 점이었습니다.
특히 아래 한 가지를 크게 느꼈습니다.
- 처음부터 어댑터를 적용했으면 더 좋았을 것 같다.
- 초기에 직접 호출하는 구조를 채택해서 중간에 리팩터링 비용이 다소 발생했다.
마치며, AI 요약
1. 어댑터 패턴은 외부 라이브러리 의존도를 줄이고 코드의 유연성과 유지보수성을 크게 높여준다.
2. 지도 API와 같은 외부 서비스 통합 시 어댑터 계층을 두는 것은 미래 변화에 대응하는 강력한 설계 전략이다.
3. 앞으로도 다양한 프로젝트에 어댑터 패턴을 적용해 더 견고하고 확장성 있는 구조를 만들고자 한다.
읽어주셔서 감사합니다.