[design-pattern] 어댑터 패턴의 이해(Adapter Pattern)
프로그램을 작성하다보면 기존에 만들어놓은 클래스와 유사한 경우가 있다. 하지만 그 클래스를 재사용하고 싶어도 조금이라도 수정하지 않고 사용하기란 어려울 것이다. adapter 패턴은 기존 클래스를 재사용할 수 있도록 중간에서 맞춰주는 역할을 한다. 즉 호환성이 없는 기존 클래스의 인터페이스를 변환해 재사용할 수 있도록 해준다. adapter 패턴은 다음 두 가지 형태로 사용된다.
[네이버 지식백과] adapter 패턴 (쉽게 배우는 소프트웨어 공학, 2015. 11. 30., 김치수)
• 클래스 adapter 패턴 : 상속을 이용한 어댑터 패턴
• 인스턴스 adapter 패턴 : 위임을 이용한 어댑터 패턴
문제
주식 시장 모니터링 앱을 만들고 있다고 상상해 보십시오. 이 앱은 XML 형식의 여러 소스에서 주식 데이터를 다운로드한 다음 사용자에게 보기 좋은 차트와 다이어그램을 표시합니다.
어느 시점에서 스마트 타사 분석 라이브러리를 통합하여 앱을 개선하기로 결정합니다. 그러나 문제가 있습니다. 분석 라이브러리는 JSON 형식의 데이터에서만 작동합니다.

XML과 함께 작동하도록 라이브러리를 변경할 수 있습니다. 그러나 이렇게 하면 라이브러리에 의존하는 일부 기존 코드가 손상될 수 있습니다. 더 나쁜 것은 처음부터 라이브러리의 소스 코드에 액세스할 수 없기 때문에 이 접근 방식이 불가능할 수 있다는 것입니다.
해결책
어댑터 를 만들 수 있습니다 . 이것은 다른 객체가 이해할 수 있도록 한 객체의 인터페이스를 변환하는 특별한 객체입니다.
어댑터는 개체 중 하나를 래핑하여 배후에서 발생하는 변환의 복잡성을 숨깁니다. 래핑된 개체는 어댑터를 인식하지도 못합니다. 예를 들어 미터와 킬로미터로 작동하는 개체를 모든 데이터를 피트와 마일과 같은 영국식 단위로 변환하는 어댑터로 래핑할 수 있습니다.
어댑터는 데이터를 다양한 형식으로 변환할 수 있을 뿐만 아니라 서로 다른 인터페이스를 가진 개체가 협업하도록 도울 수 있습니다. 작동 방식은 다음과 같습니다.
- 어댑터는 기존 개체 중 하나와 호환되는 인터페이스를 가져옵니다.
- 이 인터페이스를 사용하면 기존 개체가 어댑터의 메서드를 안전하게 호출할 수 있습니다.
- 호출을 수신하면 어댑터는 두 번째 개체에 요청을 전달하지만 두 번째 개체가 예상하는 형식과 순서로 전달합니다.
경우에 따라 통화를 양방향으로 변환할 수 있는 양방향 어댑터를 만드는 것도 가능합니다.

주식 시장 앱으로 돌아가 보겠습니다. 호환되지 않는 형식의 딜레마를 해결하기 위해 코드가 직접 작동하는 분석 라이브러리의 모든 클래스에 대해 XML-JSON 어댑터를 만들 수 있습니다. 그런 다음 이러한 어댑터를 통해서만 라이브러리와 통신하도록 코드를 조정합니다. 어댑터가 호출을 받으면 들어오는 XML 데이터를 JSON 구조로 변환하고 호출을 래핑된 분석 개체의 적절한 메서드로 전달합니다.
구조
개체 어댑터
이 구현은 개체 구성 원칙을 사용합니다. 어댑터는 한 개체의 인터페이스를 구현하고 다른 개체를 래핑합니다. 널리 사용되는 모든 프로그래밍 언어로 구현할 수 있습니다.
* 클라이언트가 요구하는 인터페이스와 호환되지 않는 인터페이스를 가져서 함께 동작하지 못하는 클래스를 동작하게 하는 패턴.
장점과 단점
장점
- 단일 책임 원칙 . 프로그램의 기본 비즈니스 논리에서 인터페이스 또는 데이터 변환 코드를 분리할 수 있습니다.
- 개방/폐쇄 원리 . 클라이언트 인터페이스를 통해 어댑터와 함께 작동하는 한 기존 클라이언트 코드를 중단하지 않고 프로그램에 새로운 유형의 어댑터를 도입할 수 있습니다.
단점
- 새로운 인터페이스와 클래스 집합을 도입해야 하므로 코드의 전반적인 복잡성이 증가합니다. 때때로 코드의 나머지 부분과 일치하도록 서비스 클래스를 변경하는 것이 더 나을 때가 있다.
다른 패턴과의 관계
- Bridge 는 일반적으로 사전에 설계되어 애플리케이션의 일부를 서로 독립적으로 개발할 수 있도록 합니다. 반면 어댑터 는 일반적으로 기존 앱과 함께 사용되어 호환되지 않는 일부 클래스가 함께 잘 작동하도록 합니다.
- 어댑터 는 기존 개체의 인터페이스를 변경하는 반면 Decorator 는 인터페이스를 변경하지 않고 개체를 향상시킵니다. 또한 Decorator 는 재귀 구성을 지원하는데 이는 Adapter 를 사용할 때 불가능합니다 .
- 어댑터 는 래핑된 객체에 다른 인터페이스를 제공하고 프록시 는 동일한 인터페이스를 제공하며 데코레이터 는 향상된 인터페이스를 제공합니다.
- Facade 는 기존 객체에 대한 새로운 인터페이스를 정의하는 반면 Adapter 는 기존 인터페이스를 사용 가능하게 만들려고 합니다. 어댑터 는 일반적으로 하나의 객체만 래핑하는 반면 Facade 는 객체의 전체 하위 시스템과 함께 작동합니다.
- Bridge , State , Strategy (및 어느 정도 Adapter )는 구조가 매우 유사합니다. 실제로 이러한 모든 패턴은 작업을 다른 개체에 위임하는 구성을 기반으로 합니다. 그러나 그들은 모두 다른 문제를 해결합니다. 패턴은 특정 방식으로 코드를 구조화하기 위한 레시피가 아닙니다. 또한 패턴이 해결하는 문제를 다른 개발자에게 전달할 수도 있습니다.