패턴명칭
Adapter
필요한 상황
이미 만들어져 제공되는 클래스 또는 API가 수정할 수 없거나 수정이 불가능한 경우, 해당 클래스 또는 API를 다른 클래스의 타입 또는 다른 API로 사용해야만 할때 사용할 수 있는 패턴이다.
예제 코드
위의 클래스다어그램에서 SamsungScanner는 컴파일된 바이너리 형태의 라이브러리로만 제공된다고 하자. 이 SamsungScanner API를 이용하여 삼성 스캐너를 제어한다. 소스코드는 제공되지 않으나 API를 소스코드 형태의 문서로 확인해보자. 소스코드는 존재하지 않으나, 실습을 전제로 융통성을 발휘하기 바란다.
package tstThread; public class SamsungScanner { public boolean ____initialize() { System.out.println("SAMSUNG SCANNER DRIVER LOADED"); return true; } public boolean ____startScanning() { System.out.println("START SCANNING"); try { Thread.sleep(1000); System.out.println("END SCANNING"); } catch (InterruptedException e) { e.printStackTrace(); } return true; } public boolean ____cancelScanning() { System.out.println("CANCEL SCANNING"); return true; } public boolean ____release() { System.out.println("FREE ALL RESOURCES FOR SAMSUNG SCANNER DRIVER"); return true; } }
모든 스캐너 장치에 대해서, 스캐너를 이용하기 위해 필요한 인터페이스는 다음과 같다.
package tstThread; public interface IScanner { boolean setup(); boolean start(); boolean cancel(); void release(); }
SamsungScanner API를 IScanner API에 맞춰 사용할 수 있도록 ScannerAdapter 클래스를 추가했으며, 다음과 같다.
package tstThread; public class ScannerAdapter implements IScanner { private SamsungScanner scanner; public ScannerAdapter(SamsungScanner scanner) { this.scanner = scanner; } @Override public boolean setup() { return scanner.____initialize(); } @Override public boolean start() { return scanner.____startScanning(); } @Override public boolean cancel() { return scanner.____cancelScanning(); } @Override public void release() { scanner.____release(); } }
이 클래스들을 사용하는 User 클래스는 다음과 같다.
package tstThread; public class User { public static void main(String[] args) { IScanner scanner = new ScannerAdapter(new SamsungScanner()); if(scanner.setup()) { scanner.start(); scanner.release(); } } }
실행결과는 다음과 같다.
SAMSUNG SCANNER DRIVER LOADED START SCANNING END SCANNING FREE ALL RESOURCES FOR SAMSUNG SCANNER DRIVER
수정할 수 없는 API인 SamsungScanner를 원하는 형태의 API인 IScanner로 사용할 수 있는 Adapter로써 ScannerAdapter를 새롭게 정의하여 SamsungScanner의 API를 성공적으로 사용하고 있다.
이 글은 소프트웨어 설계의 기반이 되는 GoF의 디자인패턴에 대한 강의자료입니다. 완전한 실습을 위해 이 글에서 소개하는 클래스 다이어그램과 예제 코드는 완전하게 실행되도록 제공되지만, 상대적으로 예제 코드와 관련된 설명이 함축적으로 제공되고 있습니다. 이 글에 대해 궁금한 점이 있으면 댓글을 통해 남겨주시기 바랍니다.