设计模式,一来项目中越来越能用到设计模式了(证明思想有了转变),二来设计模式确实需要大量的业务开发经验。
今天说一下适配器模式,自己的理解不一定正确,误人子弟的话见谅。
理解适配器
要想去理解适配器,并且在项目中真正用到适配器,就需要明白到底什么是适配器,借用百度百科对适配器的解释。
适配器是一个接口转换器,它可以是一个独立的硬件接口设备,允许硬件或电子接口与其它硬件或电子接口相连,也可以是信息接口。比如:电源适配器、三角架基座转接部件、USB与串口的转接设备等。
其实很好去理解这一段话,在实际生活中,比如你去某个地方旅游,晚上肯定要住在酒店里,你带的笔记本是三脚的插头,但是呢酒店墙上是俩孔的插座,这个时候你就需要一个转接头或者转接器,将三脚的插头转成俩脚的插头的转换器,只有这样你才能给你的电脑充上电。
在这个例子中一共出现了三个角色,三脚的插头、俩孔的插座、俩脚的插头的转换器,请记住他们方便后续理解。
回过头来我们再看看在计算机编程中是如何解释适配器的。
在计算机编程中,适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。
注意加粗的语句,将一个类的接口适配成用户所期待的,这里就对应上了例子中,只有这样你才能给你的电脑充上电,给电脑充上电就是你(用户)所期待的。
在Java中适用场景。
旧系统升级新系统,需要某个接口增加一些业务场景、A系统对接B系统,C系统现在也要对接B系统,但B系统的接口不满足C。
1、某项目需要现有的类,但项目中现有的类不兼容。
2、重复使用的类,便于拓展。
3、统一的输出接口,对输入类型未知。
适配器模式中一共有三个角色,三脚的插头【源角色】、俩孔的插座【目标角色】、俩脚的插头的转换器【适配器角色】。
Java中的适配器(示例)
在Java中适配器模式又分为:
1、类适配器
新建源角色 ThreePinSocket
(三脚插头)
package cn.com.adapters;
/**
* @author LaoCat
* @date 2022/6/14
* @description TODO
*/
public class ThreePinSocket {
/**
* @author LaoCat
* @date 2022/6/14
* @description 三脚
* @return int
*/
public int ThreePinSocket() {
return 3;
}
}
新建目标角色 ThreeToTwo
(三脚转俩脚)
package cn.com.adapters;
/**
* @author LaoCat
* @date 2022/6/14
* @description TODO
*/
public interface ThreeToTwo {
int ThreeToTwo();
}
新建适配器角色 ClassAdapter
package cn.com.adapters;
/**
* @author LaoCat
* @date 2022/6/14
* @description 类适配器
*/
public class ClassAdapter extends ThreePinSocket implements ThreeToTwo{ // 重点 继承 ThreePinSocket
@Override
public int ThreeToTwo() {
return 2;
}
}
执行
package cn.com.adapters;
/**
* @author LaoCat
* @date 2022/6/14
* @description TODO
*/
public class Run {
public static void main(String[] args) {
ClassAdapter classAdapter = new ClassAdapter();
System.out.println(classAdapter.ThreeToTwo());
}
}
可以看到该执行结果:
2
2、对象适配器
新建源角色 ThreePinSocket
(三脚插头)
package cn.com.adapters;
/**
* @author LaoCat
* @date 2022/6/14
* @description TODO
*/
public class ThreePinSocket {
/**
* @author LaoCat
* @date 2022/6/14
* @description 三脚
* @return int
*/
public int ThreePinSocket() {
return 3;
}
}
新建目标角色 ThreeToTwo
(三脚转俩脚)
package cn.com.adapters;
/**
* @author LaoCat
* @date 2022/6/14
* @description TODO
*/
public interface ThreeToTwo {
int ThreeToTwo();
}
新建适配器角色 ClassAdapter
package cn.com.adapters;
/**
* @author LaoCat
* @date 2022/6/14
* @description 对象适配器
*/
public class ObjectAdapter implements ThreeToTwo{
private ThreePinSocket twoPinSocket; // 重点
public ObjectAdapter(ThreePinSocket twoPinSocket) {
this.twoPinSocket = twoPinSocket;
}
@Override
public int ThreeToTwo() {
return 2;
}
}
执行
package cn.com.adapters;
/**
* @author LaoCat
* @date 2022/6/14
* @description TODO
*/
public class Run {
public static void main(String[] args) {
ObjectAdapter objectAdapter = new ObjectAdapter(new ThreePinSocket());
System.out.println(objectAdapter.ThreeToTwo());
}
}
可以看到该执行结果:
2
3、接口适配器(最灵活、可以理解为万能转换器,三脚转俩脚、俩脚转三脚、三脚转直连等等)
新建最初的插座 Socket
(抽象类)
package cn.com.adapters;
/**
* @author LaoCat
* @date 2022/6/14
* @description 最初的插座
*/
public abstract class Socket {
public int Socket() {
return 1;
}
}
新建源角色 ThreePinSocket
(三脚插头)FivePinSockets
(五脚插头)
package cn.com.adapters;
/**
* @author LaoCat
* @date 2022/6/14
* @description 三脚插座
*/
public class ThreePinSockets extends Socket{
@Override
public int Socket() {
return 3;
}
}
package cn.com.adapters;
/**
* @author LaoCat
* @date 2022/6/14
* @description 五脚插座
*/
public class FivePinSockets extends Socket{
@Override
public int Socket() {
return 5;
}
}
新建目标角色 ThreeToTwo
(三脚转俩脚)
package cn.com.adapters;
/**
* @author LaoCat
* @date 2022/6/14
* @description TODO
*/
public interface ThreeToTwo {
int ThreeToTwo();
}
新建适配器角色 InterfaceAdapter
package cn.com.adapters;
/**
* @author LaoCat
* @date 2022/6/14
* @description 接口适配器
*/
public class InterfaceAdapter implements ThreeToTwo{
private Socket socket; // 重点
public InterfaceAdapter(Socket socket) {
this.socket = socket;
}
@Override
public int ThreeToTwo() {
return 2;
}
}
执行
package cn.com.adapters;
/**
* @author LaoCat
* @date 2022/6/14
* @description TODO
*/
public class Run {
public static void main(String[] args) {
// 五脚
InterfaceAdapter two = new InterfaceAdapter(new FivePinSockets());
System.out.println(two.ThreeToTwo());
// 三脚
InterfaceAdapter three = new InterfaceAdapter(new ThreePinSockets());
System.out.println(three.ThreeToTwo());
}
}
可以看到该执行结果:
2
2