-
어댑터 패턴(Adapter Pattern)이란?Design Pattern/구조 디자인 패턴 2024. 4. 14. 14:55반응형
어댑터 패턴은 서로 호환되지 않는 인터페이스를 가진 클래스들이 함께 작동할 수 있도록 하는 구조적 디자인 패턴입니다. 이 패턴은 기존 시스템과 새 시스템, 라이브러리 또는 애플리케이션 간의 인터페이스 차이를 극복하기 위해 중간에 어댑터 클래스를 사용하여 호환성 문제를 해결합니다.
1. 어댑터 패턴은 주로 어디에 쓰이나?
어댑터 패턴은 주로 다음과 같은 상황에서 사용됩니다:
- 기존 시스템과 새 시스템 간의 통합: 다른 인터페이스를 가진 두 시스템이 서로 통신해야 할 때.
- 라이브러리 교체: 기존 코드를 변경하지 않고 새로운 라이브러리 또는 도구를 기존 시스템에 통합할 때.
- 플랫폼 독립적인 코드 작성: 다양한 플랫폼에서 작동하는 코드를 개발할 때.
2. Java와 Go로 어댑터 패턴을 구현할 때의 차이점
- Java: Java에서는 클래스 상속 또는 인터페이스를 사용하여 어댑터 패턴을 구현할 수 있습니다. 일반적으로 인터페이스를 통한 구현이 선호됩니다.
- Go: Go는 상속을 지원하지 않으며, 인터페이스만을 사용하여 어댑터 패턴을 구현합니다. 구조체와 인터페이스를 함께 사용하여 동일한 기능을 제공합니다.
3. 어댑터 패턴 예시
Java 예시:
// Target Interface interface MediaPlayer { void play(String audioType, String fileName); } // Adaptee class AdvancedMediaPlayer { public void playVlc(String fileName) { System.out.println("Playing vlc file. Name: " + fileName); } public void playMp4(String fileName) { System.out.println("Playing mp4 file. Name: " + fileName); } } // Adapter class MediaAdapter implements MediaPlayer { AdvancedMediaPlayer advancedMusicPlayer; public MediaAdapter(String audioType) { if (audioType.equalsIgnoreCase("vlc")) { advancedMusicPlayer = new AdvancedMediaPlayer(); } else if (audioType.equalsIgnoreCase("mp4")) { advancedMusicPlayer = new AdvancedMediaPlayer(); } } @Override public void play(String audioType, String fileName) { if (audioType.equalsIgnoreCase("vlc")) { advancedMusicPlayer.playVlc(fileName); } else if (audioType.equalsIgnoreCase("mp4")) { advancedMusicPlayer.playMp4(fileName); } } } // Client class AudioPlayer implements MediaPlayer { MediaAdapter mediaAdapter; @Override public void play(String audioType, String fileName) { if (audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")) { mediaAdapter = new MediaAdapter(audioType); mediaAdapter.play(audioType, fileName); } else { System.out.println("Invalid media. " + audioType + " format not supported"); } } } public class Main { public static void main(String[] args) { AudioPlayer audioPlayer = new AudioPlayer(); audioPlayer.play("mp3", "beyond the horizon.mp3"); audioPlayer.play("mp4", "alone.mp4"); audioPlayer.play("vlc", "far far away.vlc"); audioPlayer.play("avi", "mind me.avi"); } }
- 인터페이스 정의:
- MediaPlayer 인터페이스는 play 메소드를 정의합니다. 이 메소드는 음악 파일의 타입과 파일 이름을 매개변수로 받습니다.
- Adaptee 클래스:
- AdvancedMediaPlayer 클래스는 VLC와 MP4 파일을 재생하는 기능을 가집니다. 이 클래스는 playVlc와 playMp4 메소드를 포함하여 각각의 파일 타입에 대한 재생 로직을 구현합니다.
- Adapter 클래스:
- MediaAdapter 클래스는 MediaPlayer 인터페이스를 구현하며, AdvancedMediaPlayer 객체를 사용하여 다양한 파일 형식을 재생합니다. 이 어댑터는 audioType에 따라 적절한 메소드를 호출하여 파일을 재생합니다.
- Client 클래스:
- AudioPlayer 클래스는 기본적으로 MediaPlayer 인터페이스를 구현합니다. 특정 파일 타입을 재생할 때 MediaAdapter를 사용하여 필요한 형식에 맞게 파일을 재생할 수 있습니다. 지원하지 않는 파일 형식에 대해선 오류 메시지를 출력합니다.
Go 예시:
package main import "fmt" // Target interface type MediaPlayer interface { Play(audioType, fileName string) } // Adaptee type AdvancedMediaPlayer struct{} func (amp *AdvancedMediaPlayer) PlayVLC(fileName string) { fmt.Println("Playing vlc file. Name:", fileName) } func (amp *AdvancedMediaPlayer) PlayMP4(fileName string) { fmt.Println("Playing mp4 file. Name:", fileName) } // Adapter type MediaAdapter struct { advancedMusicPlayer *AdvancedMediaPlayer } func NewMediaAdapter(audioType string) *MediaAdapter { adapter := &MediaAdapter{ advancedMusicPlayer: &AdvancedMediaPlayer{}, } return adapter } func (adapter *MediaAdapter) Play(audioType, fileName string) { if audioType == "vlc" { adapter.advancedMusicPlayer.PlayVLC(fileName) } else if audioType == "mp4" { adapter.advancedMusicPlayer.PlayMP4(fileName) } } // Client type AudioPlayer struct{} func (player *AudioPlayer) Play(audioType, fileName string) { if audioType == "vlc" || audioType == "mp4" { adapter := NewMediaAdapter(audioType) adapter.Play(audioType, fileName) } else { fmt.Println("Invalid media. ", audioType, " format not supported") } } func main() { player := &AudioPlayer{} player.Play("mp4", "myVideo.mp4") player.Play("vlc", "myMusic.vlc") }
- 인터페이스 정의:
- Go에서는 MediaPlayer 인터페이스를 정의하여 Play 메소드를 포함합니다. 이 메소드는 오디오 타입과 파일 이름을 매개변수로 받습니다.
- Adaptee 구조체:
- AdvancedMediaPlayer 구조체는 PlayVLC와 PlayMP4 메소드를 통해 VLC와 MP4 파일 재생을 지원합니다.
- Adapter 구조체:
- MediaAdapter 구조체는 MediaPlayer 인터페이스를 구현합니다. 이 구조체는 AdvancedMediaPlayer를 포함하며, 생성자 NewMediaAdapter를 통해 초기화됩니다. Play 메소드를 통해 파일 타입에 맞는 재생 함수를 호출합니다.
- Client 구조체:
- AudioPlayer 구조체는 MediaPlayer 인터페이스를 구현하고, 지원하는 파일 형식을 확인하여 MediaAdapter를 사용해 파일을 재생합니다. 지원하지 않는 형식일 경우 오류 메시지를 출력합니다.
이러한 방식으로, Java와 Go 둘 다에서 어댑터 패턴을 활용하여 다양한 오디오 파일 타입을 처리하는 능력을 소프트웨어에 통합할 수 있습니다. 어댑터는 기존 코드와 새로운 코드 사이에서 호환성을 제공하는 중간자 역할을 수행하여 코드의 재사용성과 유지보수성을 높여줍니다.
4. 어댑터 패턴의 장단점
장점:
- 기존 코드 변경 없이 새로운 인터페이스를 소프트웨어에 통합할 수 있습니다.
- 기존 클래스가 예상하지 못한 환경에서 재사용될 수 있습니다.
단점:
- 전체 시스템의 복잡성이 증가할 수 있습니다.
- 때때로 많은 추가 객체의 생성이 필요하여, 시스템의 오버헤드가 늘어날 수 있습니다.
반응형'Design Pattern > 구조 디자인 패턴' 카테고리의 다른 글
복합체 패턴(Composite Pattern)이란? (0) 2024.04.14 퍼사드 패턴(Facade Pattern)이란? (0) 2024.04.14 브리지 패턴(Bridge Pattern)이란? (0) 2024.04.14 데코레이터 패턴(Decorator Pattern)이란? (0) 2024.04.14 프록시 패턴(Proxy Pattern)이란? (0) 2024.04.13