Java:设计模式之适配器模式Adapter

来源:互联网 发布:手机淘宝打折 编辑:程序博客网 时间:2024/05/21 10:55


模式名

适配器模式(Adapter)

定义

有时候也称包装样式或者包装。把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。一个适配使得因接口不兼容而不能在一起工作的类工作在一起,做法是将类别自己的接口包裹在一个已存在的类中。

有两类适配器模式:

·对象适配器模式 - 在这种适配器模式中,适配器容纳一个需要适配的类的实例。在这种情况下,适配器调用被适配对象的物理实体。

·类适配器模式 - 这种适配器模式下,适配器继承自已实现的类(一般多重继承)。类的适配器模式把适配的类的API转换成为目标类的API。

实例

常用的USB读卡器就是适配器的典型

适用场景

·         要使用现有对象的行为,使用一个不同的接口而不是现有的接口

·         要将现有的对象变得和一组多态的对象可交换

结构层次

 

优点

·         更好的复用性

系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。

·         更好的扩展性

在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。

 

可以对一个外部类应用多态

遵循开闭原则

如果外部类的构造函数没有很好的封装,可以通过适配器来封装。当然采用对象的工厂方法可能更适合。

局限性

需要创建额外的类来适配现有类;

 

过多的使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。



Adaptee(被适配的对象)

package com.freestudio.designpattern;//Adaptee:需要被适配的源public class UsbConnector{//提供USB设备的接口protected void connectUSBDevice(){System.out.println("UsbConnector:Connect to USB device");}}

抽象Adapter接口(目标类,扩展Adaptee的接口)

package com.freestudio.designpattern;//Targetpublic interface IMemoryAdapter{// 支持普通SD接口public void connectSD();// 迷你SD接口public void connectMiniSD();// MicroSD接口public void connectMicroSD();// MMC接口public void connectMMC();// 提供USB设备的接口public void connectUSBDevice();}
Adapter:(基于继承方式的类的适配器模式)
package com.freestudio.designpattern;//继承自Adaptee的适配器模式,扩展Adaptee(UsbConnector)没有的接口public class MemoryAdapter extends UsbConnector implements IMemoryAdapter{// 增加接口@Overridepublic void connectSD(){// TODO Auto-generated method stubSystem.out.println("MemoryAdapter:convert SD to USB interface");connectUSBDevice();}// 增加接口@Overridepublic void connectMiniSD(){// TODO Auto-generated method stubSystem.out.println("MemoryAdapter:convert MiniSD to USB interface");connectUSBDevice();}// 增加接口@Overridepublic void connectMicroSD(){// TODO Auto-generated method stubSystem.out.println("MemoryAdapter:convert MicroSD to USB interface");connectUSBDevice();}// 增加接口@Overridepublic void connectMMC(){// TODO Auto-generated method stubSystem.out.println("MemoryAdapter:convert MMC to USB interface");connectUSBDevice();}// 提供USB设备的接口@Overridepublic void connectUSBDevice(){System.out.println("MemoryAdapter:Connect to USB device");super.connectUSBDevice();}}
Adapter(基于组合方式的对象适配器模式)

package com.freestudio.designpattern;public class MemoryAdapter2 implements IMemoryAdapter{// 组合方式,内置一个Adapteeprivate UsbConnector mUsbConnector = null;public MemoryAdapter2(){if (mUsbConnector == null){mUsbConnector = new UsbConnector();// 立即初始化,后面采用延迟初始化}}// 直接绑定一个已有的Adapteepublic MemoryAdapter2(UsbConnector usbConnector){this.mUsbConnector = usbConnector;}// 增加接口@Overridepublic void connectSD(){// TODO Auto-generated method stubSystem.out.println("MemoryAdapter2:convert SD to USB interface");connectUSBDevice();}// 增加接口@Overridepublic void connectMiniSD(){// TODO Auto-generated method stubSystem.out.println("MemoryAdapter2:convert MiniSD to USB interface");connectUSBDevice();}// 增加接口@Overridepublic void connectMicroSD(){// TODO Auto-generated method stubSystem.out.println("MemoryAdapter2:convert MicroSD to USB interface");connectUSBDevice();}// 增加接口@Overridepublic void connectMMC(){// TODO Auto-generated method stubSystem.out.println("MemoryAdapter2:convert MMC to USB interface");connectUSBDevice();}// 提供USB设备的接口@Overridepublic void connectUSBDevice(){System.out.println("MemoryAdapter2:Connect to USB device");if (mUsbConnector == null){// 延迟初始化mUsbConnector = new UsbConnector();}// 有点像代理mUsbConnector.connectUSBDevice();}}

客户端调用:

static void TestAdapter(){System.out.println("======================================");//基于类的适配器模式,MemoryAdapter自身继承自Adaptee(UsbConnector),可以直接创建对象//也就是MemoryAdapter自身也是UsbConnectorIMemoryAdapter adapter = new MemoryAdapter();adapter.connectMicroSD();adapter.connectMMC();//基于对象的适配器模式//MemoryAdapter2内置或绑定一个外部的Adaptee(UsbConnector)//System.out.println("======================================");adapter = new MemoryAdapter2(new UsbConnector());adapter.connectMicroSD();adapter.connectMiniSD();}


输出:

======================================MemoryAdapter:convert MicroSD to USB interfaceMemoryAdapter:Connect to USB deviceUsbConnector:Connect to USB deviceMemoryAdapter:convert MMC to USB interfaceMemoryAdapter:Connect to USB deviceUsbConnector:Connect to USB device======================================MemoryAdapter2:convert MicroSD to USB interfaceMemoryAdapter2:Connect to USB deviceUsbConnector:Connect to USB deviceMemoryAdapter2:convert MiniSD to USB interfaceMemoryAdapter2:Connect to USB deviceUsbConnector:Connect to USB device


类适配器模式和对象适配器模式的比较:

类适配器模式

对象适配器模式

适配器继承自已实现的类(一般多重继承)。类的适配器模式把适配的类的API转换成为目标类的API。

适配器容纳一个需要适配的类的实例。在这种情况下,适配器调用被适配对象的物理实体。

采用的静态类继承的方式。

动态组合对象方式

由于适配器直接继承了Adaptee,使得适配器不能和Adaptee的子类一起工作,因为继承是静态的关系,当适配器继承了Adaptee后,就不可能再去处理  Adaptee的子类了。

一个适配器可以把多种不同的源适配到同一个目标。换言之,同一个适配器可以把源类和它的子类都适配到目标接口。因为对象适配器采用的是对象组合的关系,只要对象类型正确,是不是子类都无所谓。

适配器可以重定义Adaptee的部分行为,相当于子类覆盖父类的部分实现方法。(因为是继承关系)

要重定义Adaptee的行为比较困难,这种情况下,需要定义Adaptee的子类来实现重定义,然后让适配器组合子类。虽然重定义Adaptee的行为比较困难,但是想要增加一些新的行为则方便的很,而且新增加的行为可同时适用于所有的源。(因为是组合方式)

仅仅引入了一个对象,并不需要额外的引用来间接得到Adaptee。

需要额外的引用来间接得到Adaptee。



参考:

http://www.cnblogs.com/java-my-life/archive/2012/04/13/2442795.html