Java 디자인 패턴-10.Adapter
(Java 디자인 패턴 스터디 모집 중 : https://github.com/bluedskim/javaDesignPatterns)
Adapter(적응) 패턴
(출처:https://educationinaction.org/water-rocks-vocabulary/adaptation)
해결하려는 문제
- 인터페이스의 불일치 해결.
용도/목적
- 구조적Structural 패턴
- 어떤 인터페이스를 다른 목적의 인터페이스로 만드는 패턴.
- 클라이언트 소스 수정이 불가능한 경우 유용하다.
구성요소
- adapter(wrapper) : adaptee의 interface를 클라이언트가 원하는 target의 인터페이스로 변경하는 객체
- adaptee : 변경대상이 되는 객체
- target : 클라이언트가 원하는 인터페이스를 가지고 있는 객체
- 클라이언트 : target으로 변경된 adaptee를 사용하는 객체
고려사항
다른 유사한 패턴과 비교해보자 https://en.wikipedia.org/wiki/Adapter_pattern#Usage
- Decorator : 원래의 소스를 감싸는 방식으로 인터페이스에 동적으로 기능을 추가한다.
- Delegation : 상속을 통한 조합
- Facade : 단순화된 인터페이스 제공
클래스 다이어그램
소스
- adapter : LightningToMicroUsbAdapter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package net.dskim.desingpattern.adapter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class LightningToMicroUsbAdapter implements MicroUsbPhone {
private final LightningPhone lightningPhone;
public LightningToMicroUsbAdapter(LightningPhone lightningPhone) {
this.lightningPhone = lightningPhone;
}
@Override
public void useMicroUsb() {
log.info("MicroUsb connected");
lightningPhone.useLightning();
}
@Override
public String recharge() {
return lightningPhone.recharge();
}
}
|
- adaptee : LightningPhone.java
1
2
3
4
5
6
|
package net.dskim.desingpattern.adapter;
public interface LightningPhone {
String recharge();
void useLightning();
}
|
- target : MicroUsbPhone.java
1
2
3
4
5
6
|
package net.dskim.desingpattern.adapter;
public interface MicroUsbPhone {
String recharge();
void useMicroUsb();
}
|
- 클라이언트 : LightningToMicroUsbAdapterTest.java
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
|
package net.dskim.desingpattern.adapter;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class LightningToMicroUsbAdapterTest {
// MicroUsbPhone 충전전용 메소드를 반드시 써야 한다고 가정한다.
public String rechargeMicroUsbPhone(MicroUsbPhone microUsbPhone) {
microUsbPhone.useMicroUsb();
return microUsbPhone.recharge();
}
@Test
public void lightningToMicroUsbAdapterTest() {
Android android = new Android();
String androidRechargeResult = rechargeMicroUsbPhone(android);
log.info("androidRechargeResult={}", androidRechargeResult);
assertEquals("Recharge finished", androidRechargeResult);
Iphone iPhone = new Iphone();
//rechargeMicroUsbPhone(iPhone); //iPhone에서 micro usb를 쓰려한다면 compile 에러 발생
String iphoneWithMicroUsbRechargeResult = rechargeMicroUsbPhone(new LightningToMicroUsbAdapter(iPhone));
log.info("iphoneWithMicroUsbRechargeResult={}", iphoneWithMicroUsbRechargeResult);
assertEquals("Recharge finished", iphoneWithMicroUsbRechargeResult);
}
}
|
참고