Adapter Pattern

adapter_desc

1. 개요

우리가 사용하는 전자기기를 보면 110볼트의 플러그를 전류 코드에 꽂아서 사용 하고 있다. 하지만 다른 나라나 어떤 기기들을 보면 220볼트 규격의 전류 코드가 연결되어 있을 때가 있다. 보통 이럴때 우리는 ‘어뎁터’를 사용하여 전류를 110v에서 220v로 혹은 그 반대로 변환하여 사용한다.

이 어뎁터 사용하는 것을 보면 다음과 같다. 110v규격의 전자기기 와 220v규격의 전자기기는 아무런 변경(내부 기기의 변경 이나 조합의 변화 등)이 없고 그대로 사용 할 수 있어야 하며 중간에 ‘어댑터’라는 다른 규격을 호환시켜주는 중간 인터페이스가 존재 하게 되는 것이다. 이 어댑터의 사용을 그림으로 표현하면 다음과 같다.

adapter_desc

Client, Provider : 클라이언트와 프로바이더는 간단히 이미 만들어진 어떠한 규격 이다. 하지만 이 규격의 인터페이스는 서로 다르다. 이 서로 다른 호환성 때문에 개발자는 둘중에 하나를 내부적으로 수정 해야 한다. 하지만, 그렇게 하면 기존의 개발된 내용중 의존적인 소스가 존재 한다면 모두 바꿔야 하며 그 결과로 다른 물품의 산출물들에도 영향이 분명히 가게 될 것이다.

Adapter : 서로 다른 인터페이스 규격을 가진 클라이언트와 프로바이더의 중간에서 동작하는 어댑터는 두 인터페이스간 호환을 담당하는 역할을 지니고 있다. 이는 데이터 전송이나 기능 모두를 포함 할 것이다.

Adapter 패턴을 간단하게 말하면 기존에 만들어진 규격화 된 시스템들을 변경하지 않고 서로 호환되어 재사용 할 수 있게 만들어 주는 패턴 이라고 할 수 있다. 그래서 호환이 되지 않던 객체들을 서로간에 호환되는 어댑터를 통해서 할 일을 할 수 있게 해주는 것 이라고 할 수 있다.

 

2. 예제 및 설명

Adapter 패턴에는 2가지 종류가 있다.

1. 객체 어댑터 : 객체 구성(composition)을 사용한 패턴이다. 상속과 위임을 이용하여 두가지의 구현 방법을 가질 수 있다.

– 상속을 사용한 패턴
– 위임을 사용한 패턴

2. 클래스 어댑터 : 다중 상속을 이용한 패턴이다. 다중 상속을 지원하지 않는 JAVA에서는 사용 할 수 없다.

 

이 문서에서 알아볼 패턴은 ‘객체를 사용한 패턴’이며 두가지의 구현 스타일을 알아볼 것이다.

예제를 만들고 실행 하게 되면 다음과 같은 결과를 얻게 될 것이다.

어떤 주어진 문자열을 위와 같이 표현하는 간단한 것이다.

 

클래스 상속을 이용한 Adapter

adapter

Banner : 문자열을 여러 방법으로 출력해주는 광고물 현수막 클래스. Provider 역할.

showWithParen() : 문자열 앞과 뒤에 여는 괄호와 닫는 괄호를 출력 하는 메소드.

showWithAster() : 문자열 앞과 뒤에 *를 같이 출력하는 메소드.

 

Print : 기존에 따로 사용되었으니 이제 Banner 클래스와 같이 뭔가를 해야 하는 인터페이스. Client 역할.

 

PrintBanner : Print인터페이스와 Banner클래스 간의 Adapter 역할을 수행하는 클래스.

PrintBanner 클래스는 Banner클래스를 상속하고 Print인터페이스를 구현 하고 있다. 기능적으로 비슷하지만 다른 두개의 메소드(printWeak(), showWithParen())들을 Print인터페이스를 구현하면서 구현한 추상 메소드 printWeak()에서 Banner클래스의 showWithParen() 메소드를 호출 하는 방식 이다.

 

풀어보면 이렇다. PrintBanner의 인스턴스를 생성하고 두개의 구현된 메소드를 출력 해 보면, Banner클래스의 메소드를 호출 하는것을 확인 할 수있다. 하지만 만들어진 인스턴스는 Print를 구현하고 있기 때문에 Print인터페이스에서 구현된 다른 메소드 들도 그대로 사용 할 수 있다.

 

위임을 사용한 Adapter

지금 보게 될 패턴은 인스턴스에 의한 Adapter패턴이다. 여기서 말하는 ‘위임’이란, 어떤 메소드의 실제 처리를 다른 인스턴스의 메소드에 맡기는 것을 말한다. 기존의 패턴과 다르게 Adapter패턴에서 위임대상 클래스의 생성한 인스턴스를 갖고 그 인스턴스의 메소드를 호출 하는 방식이다. 구현체가 원하는 기능을 표현 하는 클래스의 인스턴스를 갖고 필요 메소드를 대리 하여 호출 하는 것을 보면서 wrapper 같은 느낌도 강하게 느껴 진다.

위임을 사용한 Adapter의 구현 방식은, 아래 정리된 소스를 보면 이해하기 쉬울 것 이다.

adapter_2

 

Print : 기존과 다르게 인터페이스가 아닌 추상 클래스가 된다.

 

PrintBanner : Print추상 클래스를 상속받아 추상메소드를 구현 하고 Banner인스턴스를 갖는다.

생성자에서 받은 문자열 패러미터를 이용하여 Banner인스턴스를 생성한다. 구현된 추상 메소드에서는 생서자에서 만들어진 Banner인스턴스를 이용하여 Banner의 메소드 들을 호출 하고 있다.

 

정리 해 봅시다.

Adapter 패턴은 기존의 클래스를 개조해서 필요한 클래스를 만든다. 몰론 원하는 메소드들을 그냥 새로 구현하여 만들어도 상관은 없다. 따로 관리해 가면서 만들어서 사용하는데 불편함이 없다면 말이다. 하지만 이 패턴의 주 목적은 소스 모듈의 재 사용으로 이어지는 비용의 단축이라고 할 수 있겠다.

이미 만들어져서 사용되어 있는것 들을 재사용하는것은 매력적이다. 다만 여기에서 말하는 바와 같이 전기 110v의 220v의 변환 이라던가, client와 provide의 비슷한 내용을 사용 할 수 있게 해주는 호환 인터페이스 구현 이라던가 할때 사용되는게 Adapter패턴이라고 할 수 있겠다. 이러한 패턴은 유지-보수(버전 업그레이드)에 유리 하다.

하지만 구현체가 서로 다른 내용을 가지고 억지로 붙이면 Adapter라고 보기는 힘들다. 예를들어 110v의 전류 전환을 가지고 물을 만들거나 다른 엉뚱하고 멀고 먼 기능을 이어주려 하는 것 이다. 몰론 기능적으로는 문제가 없지만 이런 형태는 문제를 일으킬 수 있는 가능성을 가지고 있다. 이 패턴의 목적은 비슷하지만 다른 인터페이스를 가진 모듈들의 호환이 주 목적이다. 그러면서 그 다른 인터페이스의 본질은 해치지 말아야 하는게 그 주 목적이다.

Adapter패턴을 잘 사용 하면 소스의 재사용으로 인한 비용 감소가 크게 다가 올 것 이며 생각보다 많이 사용하게 된다.

 

 

참고 : Java언어로 배우는 디자인 패턴 입문

You may also like

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.