放弃该放弃的是无奈,放弃不该放弃的是无能,不放弃该放弃的是无知,不放弃不该放弃的是执着。
愿自己能在自己所热爱的道路上越走越远。
适配器模式将一个类的接口转换成另一种接口,让原本不兼容的类可进行兼容. 并且从用户的角度来看适配者是解耦的, 系统设计的时候屏蔽了被适配者的内部实现细节. 用户只需要调用适配器转换出来的接口方法即可,
适配器模式分为接口适配器,类适配器、对象适配器. 三种类型,对于我们自己来说可以根据自己的实际情况来选择使用哪种适配器模式.
一、接口适配器
接口适配器需要提供一个被适配的接口,并且提供要被适配的方法.
/**
* 被适配接口: 下面主要说明接口适配器模式 .
*
* @author ZhenXinMa
* @date 2020/8/24 14:10
*/
public interface Interface0 {
void f1();
void f2();
void f3();
}
然后就是最主要的接口适配器类了, 该类实现了上面的被适配的接口,并且实现了其所有的方法,但是方法体是空实现,不去做任何实现,把实现得权利交给客户端.
/**
* 对接口进行适配的,且实现了其所有的默认方法, 但是不进行具体的方法实现.
* <p>
* 具体的方法实现由客户端(方法调用者)进行实现.
* 方法的具体实现不是由适配器类进行解决,而是用过客户端进行解决.
*
* @author ZhenXinMa
* @date 2020/8/24 14:11
*/
public class InterfaceAdaptor implements Interface0 {
@Override
public void f1() {
}
@Override
public void f2() {
}
@Override
public void f3() {
}
}
最重要的就是客户端(也是被适配接口中方法的具体实现)
public class MainClient {
public static void main(String[] args) {
InterfaceAdaptor adaptor = new InterfaceAdaptor(){
// 以匿名内部类方式去实现被适配接口的具体实现.
@Override
public void f1() {
// 具体的实现逻辑.
System.out.println("我在被适配接口里面是函数f1, 我经过适配之后我编程了f11");
}
};
adaptor.f1();
}
}
上面虽然代码和注释很少,但要注重理解.
适配器模式经常用来做旧系统的升级改造, 以及系统的维护.
二、类适配器
被适配类的标准接口
/**
* 被要求的类. 被适配类的要求.
*
* @author ZhenXinMa
* @date 2020/8/16 16:08
*/
public interface Voltage5V {
/**
* 接口方法,对外暴露, 目标只需要调用该方法即可.
*
* @return
*/
int outPut5V();
}
**被适配者,对方法进行适配. 以达到自己的要求. **
/**
* 被适配者.
*
* @author ZhenXinMa
* @date 2020/8/16 16:00
*/
public class Voltage220V {
/**
* 被适配的具体方法.
* @return
*/
public int outPut220V() {
int src = 220;
System.out.println("输出压220V : " + src);
return src;
}
}
适配器类,来对类进行适配
核心是通过继承父类和实现一个目标接口来进行适配 . 从而达到自己的要求.
/**
* 电压适配器.
* <p>
* 该适配器通过继承被适配的接口的某种实现并且实现了被适配接口.
* 通过调用父类已经实现了的方法来对适配器类的要求进行完善,从而达到对目标进行适配.
* 个人感觉该中方法对其尽心适配和对接口进行适配很类似.
*
* @author ZhenXinMa
* @date 2020/8/16 16:13
*/
public class VoltageAdapter extends Voltage220V implements Voltage5V {
/*
* --------------------------------------------------------
* Java是单继承机制: 继承的是要被适配的类,实现的接口是最后要求的结果。
* 该Voltage5V接口对外暴露, 而其提供的方法是对继承的Voltage220V类
* 经过适配之后返回的值.
* 从用户的角度来看是看不到被代理类的方法的,所以说是解耦的.
*
* --------------------------------------------------------
* */
@Override
public int outPut5V() {
// dir = 220;
// 屏蔽了方法内部实现的具体实现 .
// 该接口的适配器类可以根据自己的需要进行实现.
int dir = outPut220V();
dir = dir / 4;
System.out.println("220V经过适配器后变为" + dir + "V");
return dir;
}
}
客户端
/**
* 客户端以及使用该适配器的类.
* 当前客户端手机仅仅支持55V的电压.
*
* @author ZhenXinMa
* @date 2020/8/16 16:16
*/
public class Phone {
/**
* 将对外暴露的接口聚合到该客户端中. 具体的用法由该接口以及该客户端的使用为准.
* 该接口具体的实现需要看其客户端的调用者来具体实现.
* 在客户端注入要适配的标准. 而Voltage5V 就是被适配器类的标准.
*/
private Voltage5V voltage5V;
public Phone(Voltage5V voltage5V){
this.voltage5V = voltage5V;
}
public void charge(){
// 调用适配之后的方法.
if(voltage5V.outPut5V() == 5){
System.out.println("开始充电");
}else{
// 调用适配之后的方法失败了.
System.out.println("不能充电,等待连接适配器");
}
}
}
**测试: **
/**
* @author ZhenXinMa
* @date 2020/8/16 21:48
*/
public class Client {
public static void main(String[] args) {
Phone phone = new Phone(new VoltageAdapter());
phone.charge();;
}
}
类适配器就是将一个类现在已经不适合用了,也不能和说是不使用了吧,就是要求返回的值不符合现在系统的要求,现在为了让这个类符合系统设计的要求,我们对其进行了适配. 到最后我们也不需要对该类进行删除,也不需要重新写一个全新的类。我们只需要新增一个适配器类即可 .
三、对象适配器
被适配器类的标准接口
/**
* 被适配器类的接口(标准);
*
* @author ZhenXinMa
* @date 2020/8/24 20:43
*/
public interface Voltage220V {
int outPut220V();
}
被适配类的具体实现
/**
* 被适配类的具体实现.
*
* @author ZhenXinMa
* @date 2020/8/24 20:44
*/
public class VolTage220Vimpl implements Voltage220V {
/**
* 返回该方法标准的数据类型.
*
* @return
*/
@Override
public int outPut220V() {
int ssrc = 220;
System.out.println("当前电压为:" + ssrc);
return ssrc;
}
}
适配器类
/**
* @author ZhenXinMa
* @date 2020/8/24 20:54
*/
public class VolTageAdapter implements Voltage5V {
/**
* 注入被适配器类的实现.
*/
private Voltage220V v;
public VolTageAdapter(Voltage220V v){
this.v = v;
}
@Override
public int outPut5V() {
int dir = 0;
if (v != null) {
System.out.println("开始适配. ");
dir = v.outPut220V() / 44;
System.out.println("适配后的电压为: " + dir);
}
return dir;
}
}
使用方
public class Phone {
public void charge(VolTageAdapter adapter) {
int v = adapter.outPut5V();
if (v == 5) {
System.out.println("电压适配成功 开始充电. ");
} else {
System.out.println("电压适配失败, 不能充电. ");
}
}
}
测试方
/**
* 测试 .
*
* @author ZhenXinMa
* @date 2020/8/24 20:43
*/
public class MainClient {
public static void main(String[] args) {
Phone phone = new Phone();
phone.charge(new VolTageAdapter(new VolTage220Vimpl()));
}
}