본문으로 바로가기
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.


어댑터 패턴을 번역하면 변환기라고 할 수 있다. 변환기의 역할은 서로 다른 두 인터페이스 사이에 통신이 가능하게 하는 것이다. 어댑터 패턴을 예로 들자면 자바에서 데이터베이스를 접속할 때 사용하는 JDBC를 예를 들 수 있다. JDBC를 통해 다양한 데이터베이스를 접근할 수 있다. 어댑터 패턴은 SOLID의 개방 폐쇄 원칙(OCP)를 활용한 설계 패턴이라고 할 수 있다.


어댑터 패턴(Adapter pattern)은 클래스의 인터페이스를 사용자가 기대하는 다른 인터페이스로 변환하는 패턴으로, 호환성이 없는 인터페이스 때문에 함께 동작할 수 없는 클래스들이 함께 작동하도록 해준다.


어댑터 패턴을 이해하기 쉬운 예제

전기 소켓과 볼트를 예로 들자면 한국은 220V를 사용하지만 해외에서는 110V를 사용하는 곳이 많다. 어댑터 패턴을 공부하기 위해 억지로 다른나라는 20V를 사용할 수있고 또 어떤나라는 10V를 사용할 수 있다고 가정을 하자.


아래 예제는 소켓에서 220V를 가져오는 코드이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Volt {
    private int volt;
    
    public Volt(int volt) {
        
        this.volt = volt;
    }
    
    public void setVolt(int volt) {
    
        this.volt = volt;
    }
    
    public int getVolt() {
        
        return volt;
    }
}
 
class Socket {
    
    public Volt getVolt() {
        
        return new Volt(220);
    }
}
 
 
public class AdapterTest {
    public static void main(String[] args) {
        Socket socket = new Socket();
        
        Volt volt = socket.getVolt();
        System.out.println("volt : " + volt.getVolt() + "V");
    }
}



어댑터 패턴의 이해를 위해 2가지 방법을 아래에 작성하였다.


1. 나라별로 호환되는 Volt를 가져오기 위해 Convertible 인터페이스를 선언하고 Socket에 implement 하였다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
class Volt {
    private int volt;
    
    public Volt(int volt) {
        
        this.volt = volt;
    }
    
    public void setVolt(int volt) {
    
        this.volt = volt;
    }
    
    public int getVolt() {
        
        return volt;
    }
}
 
interface Convertible {
    public Volt get10Volt();
    public Volt get20Volt();
    public Volt get110Volt();
}
 
class Socket implements Convertible{
    
    public Volt getVolt() {
        
        return new Volt(220);
    }
 
    @Override
    public Volt get10Volt() {
        // TODO Auto-generated method stub
        
        return new Volt(10);
    }
 
    @Override
    public Volt get20Volt() {
        // TODO Auto-generated method stub
 
        return new Volt(20);
    }
 
    @Override
    public Volt get110Volt() {
        // TODO Auto-generated method stub
 
        return new Volt(110);
    }
}
 
 
public class AdapterTest {
    public static void main(String[] args) {
        Socket socket = new Socket();
        
        Volt volt220 = socket.getVolt();
        System.out.println("volt : " + volt220.getVolt() + "V");
        
        Volt volt110 = socket.get110Volt();
        System.out.println("volt : " + volt110.getVolt() + "V");
        
        Volt volt20 = socket.get20Volt();
        System.out.println("volt : " + volt20.getVolt() + "V");
        
        Volt volt10 = socket.get10Volt();
        System.out.println("volt : " + volt10.getVolt() + "V");
    }
}
 



2. 나라별로 호환되는 Volt를 가져오기 위해 SocketAdapter Class를 생성하였고, 기존에 작성된 클래스를 사용하기 위해 Socket을 extends하고 Convertible 인터페이스를 선언하여 implements하였다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
class Volt {
    private int volt;
    
    public Volt(int volt) {
        
        this.volt = volt;
    }
    
    public void setVolt(int volt) {
    
        this.volt = volt;
    }
    
    public int getVolt() {
        
        return volt;
    }
}
 
interface Convertible {
    public Volt get10Volt();
    public Volt get20Volt();
    public Volt get110Volt();
}
 
class Socket {
    public Volt getVolt() {
        
        return new Volt(220);
    }
}
 
class SocketAdapter extends Socket implements Convertible {
 
    @Override
    public Volt get10Volt() {
        // TODO Auto-generated method stub
        
        return new Volt(10);
    }
 
    @Override
    public Volt get20Volt() {
        // TODO Auto-generated method stub
 
        return new Volt(20);
    }
 
    @Override
    public Volt get110Volt() {
        // TODO Auto-generated method stub
 
        return new Volt(110);
    }
}
 
public class AdapterTest {
    public static void main(String[] args) {
        SocketAdapter socket = new SocketAdapter();
        
        Volt volt220 = socket.getVolt();
        System.out.println("volt : " + volt220.getVolt() + "V");
        
        Volt volt110 = socket.get110Volt();
        System.out.println("volt : " + volt110.getVolt() + "V");
        
        Volt volt20 = socket.get20Volt();
        System.out.println("volt : " + volt20.getVolt() + "V");
        
        Volt volt10 = socket.get10Volt();
        System.out.println("volt : " + volt10.getVolt() + "V");
    }
}



어댑터 패턴을 정의하자면 "호출당하는 쪽의 메서드를 호출하는 쪽의 코드에 대응하도록 중간에 변환기를 통해 호출하는 패턴"


어댑터 패턴을 공부하기 위해 이 예제 말고 다양한 예제를 보고 이해하는 것이 좋다. 위의 예제로 이해가 가지 않는다면 다른 블로그들이 어떻게 어댑터 패턴을 구현하고 예를 들었는지 확인해보길 바란다.


내가 작성한 블로그에 내용중에 SOLID - OCP 에 대한 글을 쓴 적이 있는데 이 글의 예제도 어댑터 패턴이라고 할 수 있다.