Java设计模式(9)-适配器模式
模式来源于生活,适配器模式最能直观的体现这一点。适配器,就是将多个原本不能共同工作的产品经过一定的处理,使得他们能够彼此协同工作的一种装置。现实生活中,有很多适配器的例子,如常见的电源适配器,可以将220V的交流电压转换为手机、电脑等电器所需的低电压;又比如,苹果手机的type-C耳机插孔,不能使用3.5mm的耳机,怎么办呢?可以增加一个耳机转换器,它就是一个适配器,能够将3.5mm耳机成功用于Type-C接口的iPhone上;还有各种转换器,如HDMI转VGA、Type-C转USB等等,都是适配器。 1. 适配器模式简介 适配器模式(Adapter pattern)的定义如下:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。 对于这个定义,需要明确几点: 首先,有一个已经存在的类A,但是不满足我们的需求,我们需要的是类B; 其次,A、B完成的功能相似,或者说,类B的功能类A其实都已经实现了,我们不想再实现一次; 第三,A、B不能共同完成工作,我们需要经过适配将A、B变得可以协同工作。 所以,什么时候可以考虑使用适配器模式? 当两个类所做的事情相同或相似,但是他们不能协同工作,此时可以通过适配器模式,但是有一个前提,就是两个类都不可能修改,如果他们频繁变动,那么首先要考虑的是重构代码来使他们统一。比如,遗留的系统、老的系统组件,他们中已经实现的功能,几乎不会修改,可以使用适配器模式。 适配器模式的主要优点如下: 客户端通过适配器可以透明地调用目标接口,更简单、直接; 复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类; 将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题。 适配器模式有三个主要角色: 目标(Target)接口:当前业务系统所期待的类,可以是抽象类或接口 被适配者(Adaptee):即现有系统或组件中已经存在的类,实现了我们所需的功能 适配器(Adapter):一个转换器,将被适配者转换为目标,让客户可以按目标接口透明的使用被适配者的功能 在java语言中,不能多继承,所以适配器模式中,我们一般会将目标申明为接口,然后通过继承或者依赖被适配者的方式来实现适配器。 适配器模式有三种形式:类适配器、对象适配器、接口适配器。 2. 类适配器模式 顾名思义,类适配器适配的是类。要想使用类的功能,java中我们只能用继承的方式,但是这违背了合成复用原则原则。尽量不要使用继承,而是使用合成的方式。 因此,类适配器最典型的缺点是,如果要替换适配器,将会变得很复杂,这种方式应该尽量不用。 这种形式的类结构如下图所示: Figure 1. 类适配器模式 Aapater类继承被适配者Adaptee,并实现目标接口Target,因此客户端可以透明的使用Target接口的api,而Adapter内部则使用Adaptee来实现Target定义的相关功能。 举个例子:用手机充电器给手机充电,假设手机需要使用5V的直流电才可以充电,但是家用电都是220V交流电,我们看看如何使用适配器模式解决这个问题。 1、首先,我们有220v的交流电,这就是被适配者Adaptee: 被适配者 class AlternatingCurrent { int outputVoltage() { (1) return 220; } } 1 被适配者拥有一个输出220V的交流电方法。 2、然后,我们新定义一个输出5V直流电的接口,这就是目标接口: 目标接口 interface DirectCurrent { int outputVoltage(); } 3、最后,定义适配器,进行适配: 适配器 class PhoneCharger extends AlternatingCurrent implements DirectCurrent { @Override public int outputVoltage() { int voltage = super.outputVoltage(); // 电压转换处理 return voltage / 44; (1) } } ...