赞
踩
微信公众号搜索:程序驴,查看更多学习笔记
举一个很贴切的例子,我们国家的家用交流电,电压是220V的,但是在美国,他们的家用电压为110V,因此如果我们要想在国外也能达到国内一样的充电体验,我们可能需要购买一个适配器,来将110V电压转换为220V。
这个例子中适配器的作用就是将现有的条件(110V)做出转化(适配器),使其符合我们的需要(220V)
其实适配器模式更贴近实际的用法是把多种有差别(但功能差不多)的接口做统一化的输出,这样不管是之后向更改接口还是切换服务提供者,都不会影响到接口使用方的业务逻辑。
再举个小例子,适配器模式其实就像是一个只注重结果的人,利用适配器,他不在乎你怎么提供的,他只在乎你提供给他的结果是否和之前的一样。只要结果一致,那你作为提供者可以随便捣鼓。
在建站过程中,OSS服务是必不可少的一环,他可以作为图床,存放我们网站的图片资源,并返回图片的访问url,但是市面上有很多的OSS服务提供者,比如需要money的阿里云,腾讯云之类的,也有可以自己手搭的Minio,这些OSS服务提供的功能接口一致,但是接口的方法名,参数类型多有不同,如果在开发过程中更换服务提供者,那可就是牵一发而动全身,想象一下下面的场景:OSS服务接口一换,原本优雅的代码,突然error99+,不是方法找不到,就是参数缺一少一,实在是让人蛋疼。
因此,我们需要一个适配器,来统一管理这些接口提供的方法,让他们最终的“结果”一致,这样不管背后的服务发生了什么变化,只要你提供的接口不变,那我的适配器就能一直工作下去。下面是代码实现。
目录结构:
StorageAdapter:
public interface StorageAdapter {
/**
* @Description: 创建
*/
boolean create(String name);
/**
* @Description: 上传
*/
boolean upload(String bucket,String obj, byte[] data);
// ............
}
StorageAdapter作为统一的适配接口,它提供一些对于每个OSS服务都拥有的功能。
AliYunServiceAdapter:
public class AliYunServiceAdapter implements StorageAdapter{
private AliYunService aliYunService;
@Override
public boolean create(String name) {
return aliYunService.createByAlY(name);
}
@Override
public boolean upload(String bucket, String obj, byte[] data) {
return aliYunService.uploadByAlY(bucket,obj,data);
}
}
阿里云的适配器接口实现类,这里模拟引入了阿里云的接口,可以看做是利用阿里云提供的接口来实现适配器中的功能,达成"结果一致"。这里特意在方法后使用了"ByAlY",意为不同的服务提供者,所提供的方法可能会有不同。
MinioServiceAdapter:
/** * @Author 林峰 * @Date 2024/4/15 0:03 * @Version 1.0 * * Minio和适配器对接 */ public class MinioServiceAdapter implements StorageAdapter{ private MinioService minioService; @Override public boolean create(String name) { return minioService.createByMinio(name); } @Override public boolean upload(String bucket, String obj, byte[] data) { return minioService.uploadByMinio(bucket,obj,data); } }
Minio的适配器接口实现类
StorageConfig:
public class StorageConfig { static String type = "AliYun"; // 如果是spring,可以直接从配置文件注入 // static String type = "Minio"; private static StorageAdapter storageAdapter; // 如果是spring,可以直接设置返回值作为Bean交由容器管理 public static StorageAdapter getStorageAdapter(){ if("AliYun".equals(type)){ storageAdapter = new AliYunServiceAdapter(); return storageAdapter; }else if("Minio".equals(type)){ storageAdapter = new MinioServiceAdapter(); return storageAdapter; }else{ throw new RuntimeException("未知的服务种类"); } } }
StorageConfig作为配置类,可以对全局的OSS服务做统一管理,可以靠其中的type实现服务自由的切换(适配器的优势),其中type可以在配置文件中进行配置,如果是微服务架构,也可以利用nacos实现远程配置,十分优雅。
这里还用到了单例设计模式,有机会再讲。
/**
* @Author 林峰
* @Date 2024/4/14 23:13
* @Version 1.0
* 适配器设计模式
*/
public class AdapterMain {
public static void main(String[] args) {
// 获取适配器接口实现类
StorageAdapter storageAdapter = StorageConfig.getStorageAdapter();
// 调用
storageAdapter.create("林峰");
}
}
从main函数可以看出,因为我们用到的是StorageAdapter这个统一的适配器接口,而用到的哪个实例化,对于我们的业务都无所谓,这极大地提高了代码的可维护性,不会导致牵一发而动全身的情况发生。
※ 以上知识点来源于个人的学习见解,如有错误,请私信联系:程序驴
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。