在设计模式中,适配器模式有时候也成为包装样式或者包装,将一个类的接口转换成用户所期待的。一个适配器使得因接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。
举一个生活中的栗子,显示器的接口分为VGA
接口、DVI
接口和HDMI
接口,但现在你有一个显示器只支持VGA
接口,但是刚巧不巧的的你只有一根DVI
接口的数据线,为了能够正常使用显示器,所以你需要一个转接头,让你的显示正常工作,那么这个转接头就是一个很恰当的适配器。
什么是适配器模式
适配器模式:将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。
在适配器模式中,我们通过增加一个新的适配器类来解决接口不兼容的问题,是的原本没有任何关系的类可以协同工作。根据适配器类与适配者类的关系不同,适配器模式可分为对象适配器,类适配器和接口适配器三种,在适配器模式中,适配器与适配者之间的关联关系。在类适配器模式中适配器与适配者之间是继承关系或者是实现关系。
以上三者在项目中都会经常用到,由于对象适配器是通过关联关系进行耦合的,因此在设计时可以做到比较灵活,而类适配器只能通过复写源角色的方法进行拓展,在实际项目中,对象适配器使用的场景相对较多。
适配器不仅可以转换不同格式的数据,其还有助于采用不同接口的对象之间的合作。它的运作方式如下:
适配器模式优缺点
在项目开发过程中减少继承关系这是一个很不错的编程习惯。适配器模式通过封装对象将复杂的转换过程隐藏在其他类中,被封装的对象是甚至完全察觉不到适配器的存在。例如你可以使用一个将所有数据转换为英制单位(如英尺和英里) 的适配器封装运行于米和千米单位制中的对象。
优点
缺点
Adapter
中都会暴漏出来示例
适配器模式的主要角色如下:
上面说适配器模式一共有三种那么就一一的把这三种适配器分别说一下,废话就不多赘述了:
对象适配器模式
类图如下所示:
代码示例:
// 目标对象 interface Target { request() : void; } // 被适配者 class Adaptee { constructor() {} // 这是源角色,有自己的的业务逻辑 public specificRequest() : void {} } // 适配器 class Adapter implements Target { private adaptee : Adaptee; constructor(adaptee : Adaptee) { this.adaptee = adaptee; } public request() : void { this.adaptee.specificRequest(); } } // 使用 const target : Target = new Adapter(new Adaptee()); target.request();
类适配器模式
对象适配器模式的主要角色如下:
类图如下所示:
代码示例:
// 目标对象 interface Target { request() : void; } // 被适配者 class Adaptee { constructor() {} // 这是源角色,有自己的的业务逻辑 public specificRequest() : void {} } // 适配器 class Adapter extends Adaptee implements Target { constructor() { super(); } public request() : void { super.specificRequest(); } }
接口配器模式
对象适配器模式的主要角色如下:
类图如下所示:
代码示例:
interface Adaptee { operation1() : void; operation2() : void; } abstract class AbsAdapter implements Adaptee { public operation1() : void {} public operation2() : void {} } class UseClass extends AbsAdapter { public operation1() : void {} // 重写该类 }
总结
适配器模式其目的是为了实现接口的复用,利用已有的代码实现新的功能,使用已经存在的部分子类,可选用随想的适配器,适配子类的父类。基于一些遗留代码的系统常常会使用该模式。在这种情况下, 适配器让遗留代码与现代的类得以相互合作。
适配器可以通过以不同抽象或接口类型实例为参数的构造函数来识别。当适配器的任何方法被调用时, 它会将参数转换为合适的格式, 然后将调用定向到其封装对象中的一个或多个方法。