**适配器模式(Adapter Pattern)**是一种结构型设计模式,它允许不兼容的接口之间进行合作。适配器模式通过创建一个适配器类来转换一个接口的接口,使得原本由于接口不兼容无法一起工作的类可以一起工作。
主要组成部分:
-
目标接口(Target Interface):
- 客户端所期望的接口。
-
适配器(Adapter):
- 实现目标接口,并持有一个具体目标对象的引用,将请求委托给该对象。
-
不兼容的接口(Adaptee):
- 现有代码中的一个接口,它是客户端想要使用的,但是不兼容。
-
客户端(Client):
- 需要使用目标接口的代码。
优点:
- 灵活性:可以在不改变现有代码的情况下,替换或扩展接口。
- 增加可重用性:使得不兼容的接口可以通过适配器进行重用。
- 解耦:客户端与不兼容的接口解耦,使代码更清晰。
使用场景:
- 当你要使用的类存在不兼容的接口时。
- 当你希望使用一些已有的子类,而它们的接口与您需要的接口不同时。
- 当你想要创建一个可以与多个不同的接口协同工作的类。
JAVA:
如何将不同类型的电器接口适配到统一的插头接口。
java
// 1、目标接口 - 电器接口
public interface ElectricSocket {
void plugIn();
}
java
//2、具体目标-美国电器
public class AmericanDevice {
public void connect() {
System.out.println("连接到美国插座!");
}
}
java
// 具体目标-欧美电器
public class EuropeanDevice {
public void plug() {
System.out.println("链接到欧美到插座!");
}
}
java
// 适配器1-美国电器适配器
public class AmericanDeviceAdapter implements ElectricSocket{
private AmericanDevice device;
public AmericanDeviceAdapter(AmericanDevice device){
this.device = device;
}
@Override
public void plugIn() {
device.connect();
}
}
java
// 适配器2-欧美适配器
public class EuropeanDeviceAdapter implements ElectricSocket{
private EuropeanDevice device;
public EuropeanDeviceAdapter(EuropeanDevice device){
this.device = device;
}
@Override
public void plugIn() {
device.plug();
}
}
java
@Test(description = "适配器模式")
public void adapterTest(){
//创建一个美国电器
AmericanDevice device = new AmericanDevice();
ElectricSocket socket = new AmericanDeviceAdapter(device);
socket.plugIn();
//创建一个欧美电器
EuropeanDevice device1 = new EuropeanDevice();
ElectricSocket socket1 = new EuropeanDeviceAdapter(device1);
socket1.plugIn();
}
GO:
假设我现在有一个运维系统,需要分别调用阿里云和 AWS 的 SDK 创建主机,两个 SDK 提供的创建主机的接口不一致,此时就可以通过适配器模式,将两个接口统一。
PS:AWS 和 阿里云的接口纯属虚构,没有直接用原始的 SDK,只是举个例子
Go
package adapter
import "fmt"
// ICreateServer 创建云主机
type ICreateServer interface {
CreateServer(cpu, mem float64) error
}
// AWSClient aws sdk
type AWSClient struct{}
// RunInstance 启动实例
func (c *AWSClient) RunInstance(cpu, mem float64) error {
fmt.Printf("aws client run success, cpu: %f, mem: %f", cpu, mem)
return nil
}
// AwsClientAdapter 适配器
type AwsClientAdapter struct {
Client AWSClient
}
// CreateServer 启动实例
func (a *AwsClientAdapter) CreateServer(cpu, mem float64) error {
err := a.Client.RunInstance(cpu, mem)
if err != nil {
return err
}
return nil
}
// AliyunClient aliyun sdk
type AliyunClient struct{}
// CreateServer 启动实例
func (c *AliyunClient) CreateServer(cpu, mem int) error {
fmt.Printf("aws client run success, cpu: %d, mem: %d", cpu, mem)
return nil
}
// AliyunClientAdapter 适配器
type AliyunClientAdapter struct {
Client AliyunClient
}
// CreateServer 启动实例
func (a *AliyunClientAdapter) CreateServer(cpu, mem float64) error {
err := a.Client.CreateServer(int(cpu), int(mem))
if err != nil {
return err
}
return nil
}
Go
package adapter
import "testing"
func TestAdapter(t *testing.T) {
// 确保 adapter 实现了目标接口
var a ICreateServer = &AliyunClientAdapter{
Client: AliyunClient{},
}
err := a.CreateServer(1.0, 2.0)
if err != nil {
return
}
var w ICreateServer = &AwsClientAdapter{
Client: AWSClient{},
}
err = w.CreateServer(2.0, 3.0)
if err != nil {
return
}
}