디자인패턴

[Java] Adapter 패턴

ZzangHo 2022. 4. 3. 23:12
728x90

디자인 패턴 공부용으로 블로그에 기록을 해본다.

공부에 참고한 자료로는 "Java 언어로 배우는 디자인 패턴 입문" 을 참고 하였다.

정의

Adapter 패턴은 Wrapper 패턴으로 불리기도 한다.  wrapper는 '감싸는 것' 이라는 의미이다. 일반 상품을 예쁜 포장지로 싸서 선물용 품으로 만드는 것처럼, 무엇인가 를 한번 포장해서 다른 용도로 사용할 수 있게 교환해 주는 것이 wrapper이며 adapter이다.
Adapter 패턴에는 다음과 같이 두 가지의 종류가 있다.

클래스에 의한 Adapter 패턴(상속을 사용한 Adapter 패턴)
인스턴스에 의한 Adapter 패턴(위임을 사용한 Adapter 패턴)


예제 프로그램

문제에서는 교류 100볼트를 직류 12볼트로 교환해 주는 어댑터를 만든다고 하지만 실제 문제는 조금 다르다. 비슷한 개념으로 아래와 같은 예제를 설명한다.

 

클래스 설명

전원과 예제 프로그램의 대응관계

전원의 비유 예제 프로그램
제공되고 있는 것 교류 100볼트 Banner 클래스(showWithParen, showWithAster)
교환장치 어댑터 PrintBanner 클래스
필요한 것 직류 12볼트 Print 인터페이스(printWeak, printStrong)

 

먼저 상속을 사용한 Adapter 패턴을 보자


Banner 클래스

package Adapter.Class;

public class Banner {
    private String string;

    public Banner(String string) {
        this.string = string;
    }

    public void showWithParen() {
        System.out.println("(" + string + ")");
    }

    public void showWithAster() {
        System.out.println("*" + string + "*");
    }
}

 

Print 인터페이스

package Adapter.Class;

public interface Print {
    public abstract void printWeak();
    public abstract void printStrong();
}

 

PrintBanner 클래스

package Adapter.Class;

public class PrintBanner extends Banner implements Print {
    public PrintBanner(String string) {
        super(string);
    }

    @Override
    public void printWeak() {
        showWithParen();
    }

    @Override
    public void printStrong() {
        showWithAster();
    }
}

 

Main 클래스

package Adapter.Class;

public class Main {
    public static void main(String[] args) {
        Print p = new PrintBanner("hello");
        p.printWeak();
        p.printStrong();
    }
}

 

PrintBanner 클래스가 어댑터의 역할을 담당ㅎ하며 이 클래스는 제공되어 있는 Banner 클래스를 상속해서, 필요로 하는 Print 인터페이스를 구현한다. PrintBanner 클래스는 showWithParen 메소드를 사용해서 printWeak를 구현하고, showWithAster 메소드를 사용해서 printStrong을 구현한다.

 

위의 Main 클래스의 실행 결과를 보면 다음과 같다.

(hello)
*hello*

Process finished with exit code 0

 

다음으로는 위임을 사용한 Adapter 패턴을 보자

 

Main 클래스, Banner 클래스는 동일하며 Print 인터페이스는 클래스라고 가정한다.

 

Print 클래스

package Adapter.Interface;

public abstract class Print {
    public abstract void printWeak();
    public abstract void printStrong();
}

 

PrintBanner 클래스

package Adapter.Interface;

import Adapter.Class.Banner;

public class PrintBanner extends Print {
    private Banner banner;

    public PrintBanner(String string) {
        this.banner = new Banner(string);
    }

    @Override
    public void printWeak() {
        banner.showWithParen();
    }

    @Override
    public void printStrong() {
        banner.showWithAster();
    }
}

 

위의 소스를 보면 이전 예에서는 자신의 상위 클래스에서 상속한 showWithParen, showWithAster 메소드를 호출하고 있었지만, 이번에는 필드를 경유해서 호출하고 있다. 즉 위임을 하고 있다.

 

PrintBanner 클래스의 printWeak 메소드가 호출되었을 때, 자신이 처리하는 것이 아니라 별도의 인스턴스인 showWithParen 메소드에게 위임하고 있다.

 

어떤 경우에 사용하는 것일까?

항상 처음부터 프로그래밍을 할 수는 없다. 이미 존재하고 있는 클래스를 이용하는 경우도 자주 있다.
특히 그 클래스가 충분한 테스트를 받아서 버그가 적고 실제로 지금까지 사용된 실적이 있다면 그 클래스를 부품으로 재이용하고 싶을 것!

Adapter 패턴은 기존의 클래스를 개조해서 필요한 클래스를 만들며 이 패턴으로 필요한 메소드를 발 빠르게 만들 수 있다. 만약 버그가 발생해도 기존 클래스에는 버그가 없으므로 Adapter 역할의 클래스를 중점적으로 조사하면 되고, 프로그램 검사도 상당히 쉬워진다고 한다.

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

[Java] Singleton 패턴  (0) 2022.04.12
[Java] Prototype 패턴  (0) 2022.04.12
[Java] Factory 패턴  (0) 2022.04.05
[Java] Template Method 패턴  (0) 2022.04.03
[Java] Iterator 패턴  (0) 2022.03.31