소스 코드를 기록하는 남자

'adapter'에 해당되는 글 1건

  1. 어댑터 패턴(Adapter Pattern)

어댑터 패턴(Adapter Pattern)

디자인 패턴

어댑터라 하면 뭐가 가장 먼저 떠오르는가? 이 글을 쓰면서 막 떠오른 것은 dp to hdmi 선이다. 이 선을 생각해보면 모니터와 컴퓨터 서로 다른 기기 사이에서 통신을 가능하도록 해주지 않는가? 모니터가 읽을 수 있는 신호로 변환해주는 역할을 하고 있다.

 

위 글을 읽으면서 Java의 JDBC가 떠올랐다면 아주 잘했다. JDBC 또한 어댑터 패턴을 이용해서 다양한 데이터베이스 시스템을 단일한 인터페이스로 조작할 수 있게 해주기 때문이다.

 

혹시 JRE도 떠올랐는가? 아주 잘 이해하고 있다. Java를 구동하는 JRE도 어댑터 패턴이라고 할 수 있다. 단순히 Java 코드만 작성한다면 어느 운영 체제에 상관없이 동작할 수 있기 때문이다.

 

혹시 OCP가 떠올랐는가? 그럼 SOLID에 대해서 한 발자국 나아가고 있다는 사실이다. 어댑터 패턴은 결국 OCP(개방-폐쇄 원칙)과 의존 역전 원칙(DIP)가 활용한 설계 패턴인 것이다.

 

이제 코드를 보자. 어댑터가 적용된 코드와 적용되지 않은 코드를 비교해보겠다.

 

어댑터가 적용되지 않은 코드

[Adapter ServiceA]

package adapterPattern;

public class ServiceA {
    void processServiceA() {
        System.out.println("this is Service A");
    }
}

[Adapter ServiceB]

package adapterPattern;

public class ServiceB {
    void processServiceB() {
        System.out.println("this is Service B");
    }
}

[ClientWithNoAdapter]

package adapterPattern;

public class ClientWithNoAdapter {
    public static void main(String[] args) {
        ServiceA sa1 = new ServiceA();
        ServiceB sb1 = new ServiceB();

        sa1.processServiceA();
        sb1.processServiceB();
    }
}

위에서 main() 메서드를 살펴보면 sa1이 호출하는 메소드와 sb1이 호출하는 메소드의 역할이 매우 비슷한 것을 알 수가 있다. 하지만 메서드명이 다르다.

 

어댑터 패턴을 적용하면 메소드명을 통일 시킬 수 있다. 각 ServiceA, ServiceB 변환기를 만들어보자.

 

[AdapterServiceA]

package adapterPattern;

public class AdapterServiceA {
    ServiceA sa1 = new ServiceA();

    void processService() {
        sa1.processServiceA();
    }
}

[AdapterServiceB]

package adapterPattern;

public class AdapterServiceB {
    ServiceB sb1 = new ServiceB();

    void processService()
    {
        sb1.processServiceB();
    }
}

[ClientWithAdapter]

package adapterPattern;

public class ClientWithNoAdapter {
    public static void main(String[] args) {
        AdapterServiceA asa1 = new AdapterServiceA();
        AdapterServiceB asb1 = new AdapterServiceB();

        asa1.processService();
        asb1.processService();
    }
}

어댑터 패턴을 적용하여 비슷한 서비스를 수행하는 메소드 이름을 통일하였다. 왜 사용하는가에 대한 의문이 든다면, 아직 객체 지향적인 이해가 부족하다고 생각한다. 예를 하나 들어서 데이터베이스 연결하는 메소드 connect() 이 있다고 하자. 데이터베이스가 다르다고 해서 connectMongo(), connectMySQL(), connectPostgreSQL() 이렇게 메소드를 짓는거보다 connect()가 좋지 않은가?

 

어댑터 패턴은 합성, 즉 객체를 속성으로 만들어서 참조하는 디자인 패턴으로, 한 문장으로 정리하면 다음과 같다.

호출당하는 쪽의 메소드를 호출하는 쪽의 코드에 대응하도록 중간에 변환기를 통해 호출하는 패턴