ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Adapter Pattern(어댑터 패턴)
    STUDY/디자인패턴 2024. 12. 8. 15:58

    어댑터 패턴이란?

    호환되지 않는 인터페이스를 가진 객체들이 협업할 수 있도록 하는 구조적 디자인 패턴

     

    문제

    XML 형식의 데이터를 사용하는 앱에서 JSON 형식의 데이터로만 작동하는 라이브러리를 사용한다고 했을 때,

     

     

    문제를 해결하기 위해 라이브러리를 XML과 작동하도록 변경할 수 있으나, 그러면 라이브러리에 의존하는 일부 기존 코드가 손상될 수 있고, 타사의 라이브러리 소스 코드에 접근하는 것 자체가 불가능할 수 있다.

     

    해결책

    어댑터는 한 객체의 인터페이스를 다른 객체가 이해할 수 있도록 변환하는 역할을 한다. 객체 중 하나를 래핑하여 클라이언트가 쉽게 사용할 수 있도록 변환하고, 래핑된 객체는 어댑터의 존재를 인식하지 못한다. 데이터를 다양한 형식으로 변환할 수 있을 뿐만 아니라 다른 인터페이스를 가진 객체들이 협업하는 데에도 도움을 줄 수 있다.

     

    객체 어댑터 구조

    객체 어댑터 구현은 객체 합성 원칙을 사용한다. 어댑터는 한 객체의 인터페이스를 구현하고 다른 객체는 래핑한다. 모든 프로그래밍 언어로 구현할 수 있다.

    • 클라이언트 : 프로그램의 기존 비즈니스 로직을 포함하는 클래스
    • 클라이언트 인터페이스 : 다른 클래스들이 클라이언트 코드와 공동 작업할 수 있도록 따라야하는 프로토콜
    • 서비스 : 일반적으로 타사 또는 레거시의 유용한 클래스를 의미, 서비스 클래스는 호환되지 않는 인터페이스를 가지고 있기 때문에 클라이언트는 서비스 클래스를 직접 사용할 수 없음
    • 어댑터 : 클라이언트와 서비스 양쪽에서 작동할 수 있는 클래스로, 서비스 객체를 래핑하는 동안 클라이언트 인터페이스를 구현한다. 어댑터는 인터페이스를 통해 클라이언트로부터 호출들을 수신한 후 이 호출을 래핑된 서비스 객체가 이해할 수 있는 형식의 호출들로 변환한다.

     

    public class Service {
        void specificMethod(int specialData) {
            System.out.println("기존 서비스, " + specialData);
        }
    }
    
    public interface ClientInterface {
        void method(int data);
    }
    
    public class Adapter implements ClientInterface {
        Service adaptee; // composition
    
        Adapter(Service adaptee) {
            this.adaptee = adaptee;
        }
    
        public void method(String data) {
        	int specialData = converToServiceFormat(data);
            adaptee.specificMethod(specialData);
        }
        
        public int converToServiceFormat(String data) {
        	return Integer.parseInt(data);
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            ClientInterface adapter = new Adapter(new Service());
            adapter.method("1");
        }
    }

     

    클래스 어댑터 구조

    클래스 어댑터 구현은 상속을 사용하며, 어댑터는 동시에 두 객체의 인터페이스를 상속한다. C++와 같이 다중 상속을 지원하는 프로그래밍 언어에서만 구현할 수 있다.

    • 클래스 어댑터 : 클라이언트와 서비스 양쪽 인터페이스를 상속하기 때문에 객체를 래핑할 필요가 없다. 변환 로직은 오버라이딩된 메서드 내에서 발생하게 된다.
    public class Service {
        void specificMethod(int specialData) {
            System.out.println("기존 서비스, " + specialData);
        }
    }
    
    interface ClinetInterface {
        void method(int data);
    }
    
    class Adapter extends Service implements ClinetInterface {
        public void method(String data) {
            int specialData = converToServiceFormat(data);
            specificMethod(specialData);
        }
        
        public int converToServiceFormat(String data) {
        	return Integer.parseInt(data);
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            ClinetInterface adapter = new Adapter();
            adapter.method(1);
        }
    }

     

    장단점

    장점

    • 단일 책임 원칙 : 프로그램의 기존 비즈니스 로직에서 인터페이스 또는 데이터 변환 코드를 분리할 수 있다.
    • 개방/폐쇄 원칙 : 클라이언트 코드가 클라이언트 인터페이스를 통해 어댑터와 작동하는 한, 기존의 클라이언트 코드를 손상시키지 않고 새로운 유형의 어댑터들을 추가할 수 있다.

     

    단점

    • 다수의 새로운 인터페이스와 클래스들을 도입해야 하므오 코드의 복잡성이 증가한다.

     

     

    참고

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

    https://inpa.tistory.com/entry/GOF-%F0%9F%92%A0-%EC%96%B4%EB%8C%91%ED%84%B0Adaptor-%ED%8C%A8%ED%84%B4-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EB%B0%B0%EC%9B%8C%EB%B3%B4%EC%9E%90

    'STUDY > 디자인패턴' 카테고리의 다른 글

    Composite Pattern(복합체 패턴)  (0) 2024.12.25
    Bridge Pattern(브리지 패턴)  (0) 2024.12.08
    Singleton Pattern(싱글턴 패턴)  (0) 2024.11.26
    Prototype Pattern(프로토타입 패턴)  (0) 2024.11.26
    Builder Pattern(빌더 패턴)  (0) 2024.11.12
Designed by Tistory.