본문 바로가기

CS study/design pattern

[디자인 패턴]어댑터(apdapter) 패턴 설명과 예시

목차

    https://refactoring.guru/ko/design-patterns/adapter

     

    어댑터 패턴

    / 디자인 패턴들 / 구조 패턴 어댑터 패턴 다음 이름으로도 불립니다: 래퍼(Wrapper), Adapter 의도 어댑터는 호환되지 않는 인터페이스를 가진 객체들이 협업할 수 있도록 하는 구조적 디자인 패턴

    refactoring.guru

     

    설명

     

    기존 클래스를 사용하고 싶지만 그 인터페이스가 나머지 코드와 호환되지 않을 때 사용

     

    어댑터 패턴은 구조적 디자인 패턴의 일종으로, 호환되지 않는 인터페이스로 인해 함께 사용할 수 없는 클래스들이 서로 상호 작용할 수 있도록 해준다.  

     

    이 패턴은 기존 시스템에 새로운 클래스를 쉽게 통합하고자 할 때 유용하게 사용된다.

    어댑터 패턴의 주요 목적은 기능의 재사용과 코드의 재활용을 극대화하는 데 있다.

     

    예시

    기존 클래스와 인터페이스

    // 기존 : MP3 플레이어
    public class MP3Player {
        public void play(String audioType, String fileName) {
            if(audioType.equalsIgnoreCase("mp3")){
                System.out.println("재생 중: " + fileName);
            } else {
                System.out.println("지원되지 않는 형식: " + audioType);
            }
        }
    }
    
    // 새로운 요구사항의 인터페이스
    public interface AdvancedMediaPlayer {
        void playFlac(String fileName);
        void playMp4(String fileName);
    }
    
    // AdvancedMediaPlayer 인터페이스를 구현한 클래스 1
    public class FlacPlayer implements AdvancedMediaPlayer {
        public void playFlac(String fileName) {
            System.out.println("재생 중 (FLAC): " + fileName);
        }
    
        public void playMp4(String fileName) {
            // MP4 파일은 지원하지 않음
        }
    }
    
    // AdvancedMediaPlayer 인터페이스를 구현한 클래스 2
    public class Mp4Player implements AdvancedMediaPlayer {
        public void playFlac(String fileName) {
            // FLAC 파일은 지원하지 않음
        }
    
        public void playMp4(String fileName) {
            System.out.println("재생 중 (MP4): " + fileName);
        }
    }

     

    클래스 1과 2의 구현가 있지만 해당 클래스 내부에서 요구하는 사항은 다른 것을 확인할 수 있다.

    이를 어떻게 기존의 MP3 클래스를 활용하여 적용할 수 있을까? 어댑터 클래스를 만들어서 해결할 수 있다.

     

    어댑터 클래스 구현

    // 어댑터 클래스
    public class MediaAdapter implements AdvancedMediaPlayer {
        AdvancedMediaPlayer advancedMusicPlayer;
    
    	//생성자 : audioType 확인 후 해당 타입에 맞는 새로운 AdvancedMediaPlayer 생성
        //if문에 따라 클래스1(Flac), 클래스2(MP4)로 나뉘어진다.
        public MediaAdapter(String audioType) {
            if(audioType.equalsIgnoreCase("flac")) {
                advancedMusicPlayer = new FlacPlayer();
            } else if (audioType.equalsIgnoreCase("mp4")) {
                advancedMusicPlayer = new Mp4Player();
            }
        }
    
        public void playFlac(String fileName) {
            advancedMusicPlayer.playFlac(fileName);
        }
    
        public void playMp4(String fileName) {
            advancedMusicPlayer.playMp4(fileName);
        }
    }

     

    생성자로 종류에 따른 필요한 어댑터 객체를 만들어서 적용할 수 있다. 이 어댑터를 기존 Legacy인 mp3와 결합한다면 문제를 해결할 수 있다.

     

    어댑터 결합

    // MP3Player를 확장하여 어댑터를 결합한 클래스
    public class AudioPlayer {
        public void play(String audioType, String fileName) {
        	//기존 mp3로 해결 가능
            if(audioType.equalsIgnoreCase("mp3")) {
                System.out.println("재생 중: " + fileName);
            } 
            //어댑터를 추가하여 해결 가능
            else if(audioType.equalsIgnoreCase("flac") || audioType.equalsIgnoreCase("mp4")) {
                MediaAdapter mediaAdapter = new MediaAdapter(audioType);
                mediaAdapter.playFlac(fileName);
                mediaAdapter.playMp4(fileName);
            } else {
                System.out.println("지원되지 않는 형식: " + audioType);
            }
        }
    }

     

    MP3 Class에 어댑터를 추가한 AudioPlayer는 어댑터 패턴을 사용하여 유연하게 기존 모듈을 활용할 수 있다.

    이처럼, 어댑터 패턴을 필요에 따라 유용하게 사용할 수 있을 것이다.

    'CS study > design pattern' 카테고리의 다른 글

    [디자인 패턴]방문자(visitor) 패턴 설명과 예  (1) 2024.04.04