[디자인 패턴] 어댑터 패턴

Narcoker·2023년 8월 4일
0

디자인 패턴

목록 보기
8/8

어댑터 패턴

클래스의 인터페이스를 클라이언트에서 사용하고자 하는 다른 인터페이스로 변환하는 디자인 패턴이다

즉, 인터페이스가 서로 호환되지 않는 클래스들이 함께 작동하도록 해주는 패턴이다.

종류

객체 어댑터(Object Adapter)

상속이 아닌 컴포지션(합성)을 사용하는 방식이다.

즉, 어댑터는 자신이 감싸고 있는 객체를 가지고 있으며,
클라이언트로부터 요청을 받으면 그 요청을 감싸고 있는 객체에게 위임한다.

클래스 어댑터(Class Adapter)

상속을 사용하는 방식이다.
즉, 어댑터는 자신이 감싸고 있는 객체를 상속하며,
클라이언트로부터 요청을 받으면 그 요청을 감싸고 있는 객체에게 위임한다.

장점

재사용

기존의 클래스를 변경하지 않고도 그 클래스의 인터페이스를 재사용할 수 있다.

유연성

서로 다른 인터페이스를 가진 클래스들을 함께 사용하는 것이 가능하게 한다.

단점

어댑터 클래스의 코드가 복잡해진다.

특히 어탭터가 어댑트해야하는 클래스의 인터페이스가 복잡할 경우 더더욱 그렇다.

예시

객체 어댑터 패턴

// 기존에 사용하고 있던 인터페이스
interface OldInterface {
    void oldMethod();
}

// 실제로 사용하고 있던 클래스
class OldClass implements OldInterface {
    @Override
    public void oldMethod() {
        System.out.println("Old method execution");
    }
}

// 새롭게 도입하려는 인터페이스
interface NewInterface {
    void newMethod();
}

// 어댑터 클래스
class Adapter implements NewInterface {
    OldInterface oldObject;

    public Adapter(OldInterface oldObject) {
        this.oldObject = oldObject;
    }

    @Override
    public void newMethod() {
        oldObject.oldMethod();
    }
}

// 클라이언트 코드
public class Client {
    public static void main(String[] args) {
        OldInterface oldObject = new OldClass();
        NewInterface adapter = new Adapter(oldObject);
        adapter.newMethod();  // Output: Old method execution
    }
}

위 코드에서 Adapter는 NewInterface를 구현하면서
내부적으로 OldInterface의 객체를 감싸고 있다.

따라서 클라이언트는 NewInterface의 메서드를 호출하더라도
실제로는 OldInterface의 메서드가 실행되는 것이다.

이처럼 어댑터 패턴을 사용하면
인터페이스가 다른 객체들을 마치 같은 인터페이스를 가진 것처럼 사용할 수 있다.

클래스 어댑터 패턴

// 어댑터 패턴을 적용하기 전의 소스 클래스
class Volt {
    private int volts;
    public Volt(int v){
        this.volts=v;
    }
    public int getVolts(){
        return volts;
    }
}

// 어댑터 패턴을 적용하기 위한 인터페이스
interface SocketAdapter {
    public Volt get120Volt();
    public Volt get12Volt();
    public Volt get3Volt();
}

// 클래스 어댑터 패턴 구현
class SocketClassAdapterImpl extends Volt implements SocketAdapter {
    SocketClassAdapterImpl() {
        super(120);
    }
    
    @Override
    public Volt get120Volt() {
    ii    return this;
  ii  }
ii
    @Override
    public Volt get12Volt() {
        Volt v= getVolt();
        return convertVolt(v,10);
    }

    @Override
    public Volt get3Volt() {
        Volt v= getVolt();
        return convertVolt(v,40);
    }
    
    private Volt convertVolt(Volt v, int i) {
        return new Volt(v.getVolts()/i);
    }
}

위의 예제에서 SocketClassAdapterImpl 클래스는 Volt 클래스를 상속하고
SocketAdapter 인터페이스를 구현한다.

이렇게 하여 SocketClassAdapterImpl는 Volt의 메서드를 사용하고
SocketAdapter의 메서드를 오버라이드하여 필요한 기능을 제공한다.

이 방식으로 SocketClassAdapterImpl 클래스는
120볼트 전력을 12볼트나 3볼트로 변환하는 어댑터 역할을 한다.

profile
열정, 끈기, 집념의 Frontend Developer

0개의 댓글