一、介绍
1、模式说明
简单来说就是,定义一个包装类,用于包装不兼容接口的对象。
1、包装类=适配器Adapter
2、被包装对象=适配者Adaptee=被适配的类
2、主要作用
把一个类的接口变成客户端所期待的另一种接口,从而使原本接口不匹配而无法一起工作的两个类能够在一起工作。
二、模式原理
1、类的适配器模式
类的适配器模式是把适配的类的API转换成目标类的API。
2、UML类图 & 组成
从这张图我么可以看出:
冲突:Target期待调用Request方法,而Adaptee并没有(即不兼容)。
解决方法:为了使Target能够使用Adaptee类里的SpecificRequest方法,故提供一个中间环节Adapter类(继承Adaptee & 实现Target接口),把Adaptee的API与Target的API衔接起来(即适配)。
3、举个例子
a.概况
背景:小北买了一个美国进口的电视机
冲突:进口电视机要求电压(110V)与国内插头标准输出电压(220V)不兼容
解决方法:设置一个适配器,将插头输出的200V转换成110V
b.实现步骤
步骤1:创建Target接口(期待得到的插头):能输出110V(将220V转换成110V);
public interface Target
{
//将220V转换输出110V(原有插头(Adaptee)没有的)
public void Convert_110v();
}
步骤2:穿件源类(原有的插头);
class PowerPort220V
{
//原有插头只能输出220V
public void Output_220V()
{
}
}
步骤3:创建适配器类(Adapter)
class Adapter220V extends PowerPort220V implements Target
{
//期待的插头要求调用Convert_110V,但原有插头没有
//因此,适配器补充上这个方法名
//但实际上Convert_110V()知识调用原有插头的Output_220V()方法的内容
//所以适配器只是将Output_220V()作了一层封装,封装成Target可以调用的Convert_110V()而已
@override
public void Convert_110V()
{
this.Output_220V;
}
}
步骤4:定义具体使用目标类,并通过Adapter类调用所需要的方法从而实现目标(不需要通过原有插头)
//进口机器类
class ImportedMachine
{
@override
public void Word()
{
System.out.printIn("进口机器正常运行");
}
}
//通过Adapter类从而调用所需要的方法
public class AdapterPattern
{
public static void main(String[] args)
{
Target mAdapter220V = new Adapter220V();
ImportedMachine mImportedMachine = new ImportedMachine();
//用户拿着进口机器插上适配器(调用Convert_110V()方法)
//再将适配器插上原有插头(Convert_110V()方法内部调用Output_220V()方法输出220V)
//适配器只是个外壳,对外提供110V,但本质还是220V进行供电
mAdapter220V.Convert_110V();
mImportedMachine.Work();
}
}
三、优缺点
1、优点
更好的复用性。
系统需要使用现有的类,而此类的接口不符合系统的需要,那么通过适配器模式就可以让这些功能得到更好的复用。
透明、简单。
客户端可以调用同一接口,因而对客户端来说是透明的。这样做更简单也更直接
更好的扩展性。
在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。
解耦性。
将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码。
开–闭原则。
同一个适配器可以把适配者类和它的子类都适配到目标接口;可以为不同的目标接口实现不同的适配器,而不需要修改待适配类。
2、缺点
过多的使用适配器,会让系统非常零乱,不易整体进行把握。