본문 바로가기
Java

어댑터 패턴 (Adapter pattern) 이란?

by 승화니' 2021. 5. 19.

 

Adapter Design Pattern UML Diagram

 

어댑터 디자인 패턴을 쉽게 예를 들어, 실생활의 어댑터는 110v를 220v로 변경해주거나 그 반대로 해주는 흔히 돼지코라고 불리는 변환기를 예로 들 수 있습니다. 


즉, 프로그래밍 세계에서는 호환성이 없는 기존 클래스의 인터페이스를 변환하여 재사용을 할 수 있습니다. 더 나아가 향후 인터페이스가 바뀌더라도 그 변경 내역 은 어댑터에 캡슐화되기 때문에 클라이언트는 바뀔 필요가 없어집니다.

 

SOLID 중에서 이는 개방 폐쇄 원칙(OCP)을 따르며, SOLID(객체 지향 설계)에 대한 내용도 아주 중요한 내용이라 이와 관련된 소개는 디자인 패턴 시리즈가 완결된 후 코드와 같이 차례대로 소개해 드리겠습니다.

 

그러면, 110v를 220v로 변환해주는 아래의 예제로 다뤄 보겠습니다.

 

 

첫 번째. 110v에 사용되는 가전과 220v에 사용되는 가전의 interface

 

public interface Electronic110V {

    void powerOn(); // 전원을 키다.

}

 

먼저, 110v의 Electronic110V라는 interface를 만들어주고, powerOn이라는 메서드를 만들어 줍니다. 

 

그리고,

 

public interface Electronic220V {

    void connect(); // 전원을 키다.

}

 

다른 개념의 220v의 Electronic220V라는 interface를 만들어주고, 220v는 110v에 비해 조금 진화한 형태로 구분할 수 있게 connect라는 메서드를 만들어 줍니다.

 

 

두 번째. 제품이 있다는 가정으로 110v의 가전과 220v의 가전

 

public class HairDryer implements Electronic110V {
    
    @Override
    public void powerOn() {
        System.out.println("헤어드라이기 110v On");
    }
    
}

 

해어드라어기에 대한 110v 가전을 만들기 위해 HairDryer라는 Class를 만들어 110v의 Electronic110V를 implements로 상속시켜 재정의 하여 구현합니다.

 

이와 마찬가지로,

 

public class AirConditioner implements Electronic220V {

    @Override
    public void connect() {
        System.out.println("에어컨 220v On");
    }
    
}

 

에어컨에 대한 220v 가전을 만들기 위해 AirConditioner라는 Class를 만들어 220v의 Electronic220V를 implements로 상속시켜 재정의 하여 구현합니다.

 

이어 청소기에 대한 220v도 에어컨과 똑같이 만들어 구현합니다.

 

public class Cleaner implements Electronic220V {

    @Override
    public void connect() {
        System.out.println("청소기 220v On");    
    }
    
}

 

 

세 번째. 테스트

 

public class AdapterMain {

    public static void main(String[] args) {

    }

    /**
     * 110v 콘센트
     * @param electronic110V
     */
    public void connect(Electronic110V electronic110V) {
        electronic110V.powerOn();
    }

}

 

테스트하기 전, Main 메서드 밑에 일반 가정집에서 일반 110v만 받을 수 있는 콘센트를 만듭니다.

 

public class AdapterMain {

    public static void main(String[] args) {

	// 헤어드라이기
        HairDryer hairDryer = new HairDryer();
        // 110v 콘센트에 전원연결.
        connect(hairDryer);
        
    }

    /**
     * 110v 콘센트
     * @param electronic110V
     */
    public static void connect(Electronic110V electronic110V) {
        electronic110V.powerOn();
    }

}

 

그럼 어느 정도 다 구성이 되었으니, Main 메서드에 헤어 드라이기를 110v 콘센트에 연결하여 작동을 시켜 보겠습니다.

 

110v 헤어드라이기 연결 테스트

 

잘 작동이 되고, 220v 청소기를 사 왔다는 가정으로 Main 메서드에 110v 콘센트를 연결하여 작동해보겠습니다.

 

하지만, 청소기는 220v에서만 요구를 하고 있고, 220v를 implements로 상속받았기 때문에 110v 콘센트 사용할 수 없어 에러를 뿜어냅니다.

 

이런 상황에서 현실세계에서는 돼지코를 가져와 110v코드에 껴줘야 하고, 이런 변환시켜 주는것을어댑터라고 하는데요!

 

어댑터를 따로 SocketAdapter Class를 만들어 구현합니다.

 

public class SocketAdapter implements Electronic110V {

    public Electronic220V electronic220V;

    public SocketAdapter(Electronic220V electronic220V) {
        this.electronic220V = electronic220V;
    }

    @Override
    public void powerOn() {
        electronic220V.connect();
    }
    
}

 

이 어댑터는 220v로 들어와서 110v로 들어가기 때문에 110v를 implements로 상속을 받고, 기본으로 220v로 받기 위해 생성자에 220을 받도록 할당합니다.

 

그리고 110v의 Override 된 함수에 할당이 됐을 때, 220v의 connect에 호출하게 됨으로 써 중간에 220v가 110v로 바뀌면서 전달할 수 있습니다.

  

다시 Main 메서드로 돌아와 SocketAdapter라는 어댑터로 에러가 뿜어져 나오는 헤어드라이기를 연결해볼까요?

 

public class AdapterMain {

    public static void main(String[] args) {

        // 220v 청소기
        Cleaner cleaner = new Cleaner();
        // cleaner를 110v 어댑터에 연결한다.
        Electronic110V adapter = new SocketAdapter(cleaner);
        // 110v 어댑터를 110v 콘센트에 연결한다.
        connect(adapter);
        
    }

    /**
     * 110v 콘센트
     * @param electronic110V
     */
    public static void connect(Electronic110V electronic110V) {
        electronic110V.powerOn();
    }

}

 

cleaner라는 청소기를 110v 콘센트를 바로 connect 시키지 말고, SocketAdapter에 전달을 시킨 뒤 110v 콘센트 connect에 adapter를 껴주시면 됩니다.

 

220v 청소기를 110v 어댑터를 활용하여 110v 콘센트에 연결성공!

 

이렇듯 중간에 변환해주는 접점을 어댑터 패턴이라 불립니다.

 

위와 관련된 코드는 
https://github.com/lsh955/java_design_pattern/tree/master/src/com/company/design/adapter에서 확인하실 수 있습니다.
 

lsh955/java_design_pattern

Contribute to lsh955/java_design_pattern development by creating an account on GitHub.

github.com

 

'Java' 카테고리의 다른 글

옵저버 패턴 (Observer pattern) 이란?  (0) 2021.05.23
싱글턴 패턴 (Singleton pattern) 이란?  (0) 2021.05.05

댓글