개발 도서

디자인 패턴 - 어댑터 패턴과 퍼사드 패턴

백수왕 2023. 12. 12. 02:08

어댑터 패턴

특정 클래스 인터페이스를 요구하는 다른 인터페이스로 변환합니다. 인터페이스가 호환되지 않아 같이 쓸 수 없던 클래스를 사용할 수 있게 도와줍니다.

즉, 호환성 문제를 해결해줍니다.

 

 

구조

어댑터 패턴에는 두 종류가 있습니다. 하나는 객체 어댑터, 다른 하나는 클래스 어댑터 입니다.

 

클래스 어댑터 패턴은 어댑터와 어댑티가 타겟 클래스를 동시에 상속받아 구현하므로 다중 상속을 지원하는 언어에서 사용할 수 있습니다.

 

객체 어댑터 패턴은 구성을 통해 더 유연하게 적용할 수 있으며 자바같은 다중 상속을 지원하지 않는 언어에서는 주로 사용합니다.

또한 클래스 간의 느슨한 결합으로 더 좋은 유지보수성을 얻을 수 있습니다.

 

가장 큰 차이점은 클래스 어댑터는 상속을 사용하고, 객체 어댑터는 구성을 사용합니다.

 

 

클래스 어댑터 클래스 다이어 그램

 

객체 어댑터 클래스 다이어 그램

 

  • Client : 기존 비지니스 로직이 포함된 클래스
  • Target : 클라이언트가 기대하는 기능을 담은 인터페이스
  • Adapter : 호환성이 없는 클래스를 연결해 주는 인터페이스 구현체
  • Adaptee : 호환이 필요한 대상

 

 

어댑터 패턴 예제

자바를 사용하기 때문에 객체 어댑터로 예제를 만들어 보겠습니다.

interface Target {
    void providePower();
}



class Adaptee {
    public void specificPower() {
        System.out.println("220V로 변환");
    }
}



class Adapter implements Target {
    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    public void providePower() {
        adaptee.specificPower();
    }
}



public class Client {
    public static void main(String[] args) {

        Adaptee adaptee = new Adaptee();

        Target target = new Adapter(adaptee);

        target.providePower();
    }
}

// 220V로 변환

 

 

퍼사드 패턴

서브 시스템에 있는 일련의 인터페이스를 통합 인터페이스로 묶어 줍니다. 또한 고수준 인터페이스도 정의하므로 서브시스템을 더 편리하게 사용할 수 있습니다.

즉, 클라이언트를 복잡한 서브 시스템과 분리하는 역할을 합니다.

 

 

퍼사드 패턴 예제

// 퍼사드 클래스
public class SmartHome {
    private LightSystem lightSystem;
    private HeatingSystem heatingSystem;

    public SmartHome() {
        this.lightSystem = new LightSystem();
        this.heatingSystem = new HeatingSystem();
    }

    public void leaveHome() {
        lightSystem.turnOffAllLights();
        heatingSystem.setTemperature(30);
    }
}



// 서브 클래스
public class LightSystem {
    public void turnOffAllLights() {
        System.out.println("모든 조명을 끕니다.");
    }
}

public class HeatingSystem {
    public void setTemperature(int temperature) {
        System.out.println("난방 온도를 " + temperature + "도로 설정합니다.");
    }
}



public class Test {
    public static void main(String[] args) {
        SmartHome smartHome = new SmartHome();

        smartHome.leaveHome();
    }
}

퍼사드 패턴을 사용하여 각 시스템을 별도로 호출하는 것이 아닌 단 하나의 퍼사드 클래스만 호출하여 코드가 간단해 집니다.

만약 퍼사드 패턴을 사용하지 않을 경우

public class Test {
    public static void main(String[] args) {
        LightSystem lightSystem = new LightSystem();
        lightSystem.turnOffAllLights();

        HeatingSystem heatingSystem = new HeatingSystem();
        heatingSystem.setTemperature(30);
    }
}

각 시스템을 별도로 호출하여 코드가 복잡해집니다.

 

 예제에선 두 개의 기능만 있는데 만약 에어컨과 커텐 가스 등등 여러 기능들이 추가가 된다면 코드가 복잡해질 수 있습니다. 

 

 

디자인 원칙 - 최소 지식 원칙

객체 사이의 상호작용은 될 수 있으면 아주 가까운 '친구' 사이에서만 허용하는 편이 좋다.

진짜 절친에게만 이야기해야 한다.