适配器模式
# 适配器模式
生活中类似的场景比如电源插座转换头、手机充电转换头、显示器转换头、电压转换等。
# 定义
适配器模式,是指将一个类的接口转换为用户期望的另一个接口,使原本接口不兼容的类可以一起工作。
# 结构
目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口(已存在的类,具有不兼容的接口)。
适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。
- img: https://bitouyun.com/images/design-pattern/adapter.png
link: https://bitouyun.com/images/design-pattern/adapter.png
name: 适配器模式
2
3
# 优点
解决接口不兼容问题:适配器模式可以让原本不兼容的类能够协同工作,提供一个中间层来进行接口转换。
复用现有功能:适配器模式可以重用已有的类,通过适配器对其进行包装和转换,而无需修改现有代码。
灵活性和扩展性:适配器模式允许在不修改现有代码的情况下引入新的类,使得系统更加灵活,并支持后续的扩展和变化。
# 缺点
增加复杂性:引入适配器模式会增加一层额外的间接性,可能会增加代码的复杂性和理解难度。
过多的适配器类:在系统中存在大量不兼容的类时,可能需要创建大量的适配器类,增加代码量和维护成本。
# 应用场景
已经存在的类的方法和需求不匹配(方法结果相同或类似)的情况。
将已有类集成到新系统中:当需要将已有的类集成到一个新的系统中,但由于接口不兼容而无法直接使用时,可以使用适配器模式进行接口转换。
系统扩展和演化:当系统需要支持后续的扩展和演化,可能需要引入新的类来与已有类一起工作,可以使用适配器模式来实现兼容性。
# 示例代码1
场景
民用电220V交流电,但手机使用5V直流电,因此给手机充电时需要使用电源适配器进行转换,将220V交流电转换成5V直流电。
/**
* 220V交流电
* 需要被适配的类,是已存在的类,具有不兼容的方法
*/
@Slf4j
public class AC220 {
public int outputAC220V() {
int output = 220;
log.info("输出:{}V电压", output);
return output;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 5V直流电
* 目标接口,期望的接口
*/
public interface DC5 {
int output5V();
}
2
3
4
5
6
7
/**
* 电源适配器
* 转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。
*/
@Slf4j
public class PowerAdapter implements DC5{
private AC220 ac220;
public PowerAdapter(AC220 ac220) {
this.ac220 = ac220;
}
@Override
public int output5V() {
int input = ac220.outputAC220V();
// 变压器
int output = input / 44;
log.info("输入电压:{},输出电压:{}", input, output);
return output;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 测试类
*/
@Slf4j
public class Client {
public static void main(String[] args) {
// 输入220V交流电,适配后输出5V直流电
PowerAdapter adapter = new PowerAdapter(new AC220());
int output = adapter.output5V();
log.info("将220V交流电转成{}V直流电", output);
}
}
2
3
4
5
6
7
8
9
10
11
12
// Make sure to add code blocks to your code group
# 示例代码2
场景2
支付模块支持多种支付方式,如阿里支付、微信支付,方便后续扩展其它支付方式,使用适配器模式提供一致的接口给客户端使用。
/**
* 目标接口Payment
*/
public interface Payment {
void pay();
}
2
3
4
5
6
/**
* 阿里支付类
*/
@Slf4j
public class AlipayPayment {
public void alipay(){
log.info("阿里支付......");
}
}
/**
* 微信支付类
*/
@Slf4j
public class WeChatPayPayment {
public void weChatPay(){
log.info("微信支付......");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 支付适配器类
*/
@Slf4j
public class PaymentAdapter implements Payment {
private AlipayPayment alipayPayment;
private WeChatPayPayment weChatPayPayment;
public PaymentAdapter(AlipayPayment alipayPayment) {
this.alipayPayment = alipayPayment;
}
public PaymentAdapter(WeChatPayPayment weChatPayPayment) {
this.weChatPayPayment = weChatPayPayment;
}
@Override
public void pay() {
if (alipayPayment != null) {
alipayPayment.alipay();
} else if (weChatPayPayment != null) {
weChatPayPayment.weChatPay();
}
}
}
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
/**
* 测试类
*/
public class Client {
public static void main(String[] args) {
// 阿里支付
AlipayPayment alipayPayment = new AlipayPayment();
PaymentAdapter paymentAdapter = new PaymentAdapter(alipayPayment);
paymentAdapter.pay();
// 微信支付
WeChatPayPayment weChatPayPayment = new WeChatPayPayment();
PaymentAdapter paymentAdapter2 = new PaymentAdapter(weChatPayPayment);
paymentAdapter2.pay();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Make sure to add code blocks to your code group