어댑터 패턴은 클래스의 인터페이스를 사용자가 기대하는 다른 인터페이스로 변환하는 패턴으로, 호환성이 없는 인터페이스 때문에 함께 동작할 수 없는 클래스들이 함께 작동하도록 해줍니다.
여기서 어댑터라는 개념은 노트북 어댑터(Adapter)를 생각하시면 됩니다. 콘센트 전원에서 나오는 전기는 대개 교류 200V이지만 노트북은 직류 120V입니다. 그렇지만 우리는 노트북을 사용할 때 아무런 불편 없이 노트북 선을 전원에 그대로 꽃아 사용할 수 있습니다.그 이유는 중간에 교류 200V를 120V로 바꾸어 주는 어댑터가 존재하기 때문입니다.
이와 비슷한 맥락에서 '어댑터 패턴'은 노트북 어댑터의 역할 처럼 기존 클래스를 재사용할 수 있도록 중간에서 맞춰주는 역할을 합니다. 다시말하자면, 호환성이 없는 기존 클래스의 인터페이스를 변환해 재사용할 수 있도록 해줍니다.
어댑터 패턴은 아래와 같이 2가지 형태로 사용됩니다.
JDK에서 사용되는 대표적인 Adapter pattern으로는 InputStreamReader
가 있습니다.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
위 코드를 보면 InputStreamReader
클래스는 System.in
클래스의 Adapter역할을 하며, System.in
은 Adaptee의 역할을 하고 있습니다.
public InputStreamReader(InputStream in) {
super(in);
try {
sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
} catch (UnsupportedEncodingException e) {
// The default encoding should always be available
throw new Error(e);
}
}
InputStreamReader 생성자에서는 InputStream
클래스를 받아 사용합니다.
자바의 InputStream
은 바이트 스트림을 읽어들입니다. 하지만, BufferedReader
는 캐릭터인풋 스트림을 읽어들이므로, 둘은 호환되지 않습니다. 하지만, 이 둘을 연결시켜 주는 어댑터인 InputStreamReader
를 사용함으로써 호환되지 않는 두 개의 기능을 연결시켰습니다.
아래는 UML구조입니다.
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String name = "";
while (!name.equals("stop")) {
System.out.println("Enter data: ");
name = br.readLine();
System.out.println("data is: " + name);
}
br.close();
}
https://m.blog.naver.com/dktmrorl/222084011455
https://refactoring.guru/design-patterns/adapter
https://yaboong.github.io/design-pattern/2018/10/15/adapter-pattern/