어댑터 패턴(Adapter Pattern)은 호환되지 않는 인터페이스를 가진 클래스들이 함께 동작할 수 있도록 변환해주는 구조 패턴이다.
쉽게 말해, 서로 다른 인터페이스 사이를 연결해주는 중간 다리 역할을 한다.
두 개의 서로 다른 시스템이 함께 동작해야 할 때, 직접적으로 코드를 수정하면 기존 코드에 영향을 미쳐 시스템 안정성이 저하될 수 있다.
이럴 때 어댑터 패턴을 사용하면 다음과 같은 장점을 얻을 수 있다:
Client --> Target <---- Adapter ----> Adaptee
MP3 플레이어가 MP4 파일과 같은 다른 포맷도 재생할 수 있도록 만들고 싶다.
MP3 플레이어는 기존에 제공된 인터페이스를 따르고, MP4 재생 기능은 어댑터를 통해 추가한다.
// Target 인터페이스
interface MediaPlayer {
void play(String audioType, String fileName);
}
// Adaptee 클래스
class AdvancedMediaPlayer {
void playMP4(String fileName) {
System.out.println("Playing MP4 file: " + fileName);
}
void playVLC(String fileName) {
System.out.println("Playing VLC file: " + fileName);
}
}
// Adapter 클래스
class MediaAdapter implements MediaPlayer {
private AdvancedMediaPlayer advancedMediaPlayer;
public MediaAdapter(String audioType) {
if (audioType.equalsIgnoreCase("mp4")) {
advancedMediaPlayer = new AdvancedMediaPlayer();
}
}
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("mp4")) {
advancedMediaPlayer.playMP4(fileName);
} else if (audioType.equalsIgnoreCase("vlc")) {
advancedMediaPlayer.playVLC(fileName);
}
}
}
// Concrete Target 클래스
class AudioPlayer implements MediaPlayer {
private MediaAdapter mediaAdapter;
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("mp3")) {
System.out.println("Playing MP3 file: " + fileName);
} else if (audioType.equalsIgnoreCase("mp4") || audioType.equalsIgnoreCase("vlc")) {
mediaAdapter = new MediaAdapter(audioType);
mediaAdapter.play(audioType, fileName);
} else {
System.out.println("Invalid media format: " + audioType);
}
}
}
// 클라이언트 코드
public class Main {
public static void main(String[] args) {
MediaPlayer player = new AudioPlayer();
player.play("mp3", "song.mp3");
player.play("mp4", "video.mp4");
player.play("vlc", "movie.vlc");
player.play("avi", "unsupported.avi");
}
}
Playing MP3 file: song.mp3
Playing MP4 file: video.mp4
Playing VLC file: movie.vlc
Invalid media format: avi
InputStreamReader
는 InputStream을 Reader로 변환하는 어댑터 역할을 한다.어댑터 패턴(Adapter Pattern)은 기존 시스템과 새 시스템 간의 간극을 메우는 데 효과적인 방법을 제공한다.
특히, 코드 변경 없이 새로운 요구사항에 유연하게 대처할 수 있는 강력한 도구로 활용된다.
아래 글에서 다른 디자인 패턴들을 확인할 수 있다.
디자인 패턴 모음