电子设备之间有线数据传输常用USB来进行,例如现在某果笔记本统一采用了USB type-c接口,而目前绝大多数即用即插存储介质用的是USB type-b接口,那么为了适配,往往需要消费者购买转换坞等中间设备进行过渡,这种模式其实就是程序设计中常用的适配器模式,另一个形象的实例就是扳手为了拧动型号的螺栓,也需要相应的转接头进行适配。
1.适配器模式
以上两个例子,体会一下就能明白适配器模式的用途了。
适配器模式(Adapter Pattern),将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作。
下面是适配器模式的UML类图:
Target: 客户端所希望的接口;
Adapter: 适配器,将Target请求适配到Adaptee的相应接口中处理;
Adaptee: 被适配的接口。
一般什么时候使用适配器模式呢?系统比较陈旧的时候,客户端更新,而短时间没有办法更新系统,而采取添加中间层的办法采用适配器模式来兼容。
2.代码实现
场景是这样的:小红去欧洲旅游,发现欧标插座都是两个圆孔的,需要相应的欧标插头才能插入,而小红的手机充电器的插头是国标的,怎么办呢?只能用适配器,国标插头插入适配器的国标一端,适配器的另一端欧标插头插入欧标插座。
Socket,定义了插座,提供电源
/** * 插座,供电 */ interface Socket { void supplyPower(); }
欧洲标准插座
/** * 欧洲标准的插座,只能插入欧洲标准插头 */ class EuroSocket implements Socket { @Override public void supplyPower() { System.out.println("欧洲插座供电。"); } }
适配器类,根据开闭原则和单一职责原则,可以实现各种标准插座的适配器
/** * 适配器接口,可以实现各种适配器 */ interface Adapter { void plugin(); }
这里只实现欧洲插座标准的适配器
/** * 欧洲插座适配器 */ class EuroSocketAdapter implements Adapter { private Socket euroSocket; public EuroSocketAdapter(final Socket socket) { euroSocket = socket; } @Override public void plugin() { System.out.println("适配器插入欧洲插座。"); euroSocket.supplyPower(); } }
调用
public class AdpaterDemo { public static void main(String[] args) { Adapter adapter = new EuroSocketAdapter(new EuroSocket()); System.out.println("小红将充电器插入适配器。"); adapter.plugin(); } }
输出结果
小红将充电器插入适配器。
适配器插入欧洲插座。
欧洲插座供电。
3.总结
下面是与适配器模式“类似”模式与适配器模式的区别:
适配器模式:为了让客户使用老接口而新增的、客户所期望的接口,代理模式的着眼点在于封装“转换”这一过程;
代理模式:与被代理的接口相同,控制客户的访问, 代理模式的着眼点在于封装“控制访问”这一过程;
装饰器模式:加强接口的功能,增加额外效果,装饰器模式着眼点在于封装“额外操作”这一过程;
外观模式:提供一个简洁的接口,内部处理一系列复杂的逻辑,外观模式着眼于封装“复杂实现”这一过程。