网站开发 手机 验证码,爱廷玖达泊西汀,深圳推广公司哪家最好,网站做的拖管不行 怎么投诉1、简介
1.1、概述
有的笔记本电脑的工作电压是20V#xff0c;而我国的家庭用电是220V#xff0c;如何让20V的笔记本电脑能够在220V的电压下工作#xff1f;答案是引入一个电源适配器#xff08;AC Adapter#xff09;#xff0c;俗称充电器#xff0f;变压器。有了这…1、简介
1.1、概述
有的笔记本电脑的工作电压是20V而我国的家庭用电是220V如何让20V的笔记本电脑能够在220V的电压下工作答案是引入一个电源适配器AC Adapter俗称充电器变压器。有了这个电源适配器生活用电和笔记本电脑即可兼容如下图所示
在软件开发中有时也存在类似这种不兼容的情况也可以像引入一个电源适配器一样引入一个被称为适配器的角色来协调这些存在不兼容的结构这种设计方案即为适配器模式。
与电源适配器相似在适配器模式中引入了一个被称为适配器Adapter的包装类而它所包装的对象称为适配者Adaptee即被适配的类。适配器的实现就是把客户类的请求转化为对适配者的相应接口的调用。也就是说当客户类调用适配器的方法时在适配器类的内部将调用适配者类的方法而这个过程对客户类是透明的客户类并不直接访问适配者类。因此适配器让那些由于接口不兼容而不能交互的类可以一起工作。
1.2、定义
适配器模式Adapter Pattern将一个接口转换成客户希望的另一个接口使接口不兼容的那些类可以一起工作其别名为包装器Wrapper。适配器模式既可以作为类结构型模式也可以作为对象结构型模式。 注在适配器模式定义中所提及的接口是指广义的接口它可以表示一个方法或者一组方法的集合。
2、解析
在适配器模式中通过增加一个新的适配器类来解决接口不兼容的问题使得原本没有任何关系的类可以协同工作。根据适配器类与适配者类的关系不同适配器模式可分为对象适配器模式和类适配器模式两种。在对象适配器模式中适配器与适配者之间是关联关系
2.1、对象适配模式
在类适配器模式中适配器与适配者之间是继承或实现关系。在实际开发中对象适配器模式的使用频率更高其结构如下图所示 可以看出在对象适配器模式结构图中包含以下3个角色
Target目标抽象类目标抽象类定义客户所需接口可以是一个抽象类或接口也可以是具体类。Adapter适配器类适配器可以调用另一个接口作为一个转换器对Adaptee和Target进行适配。适配器类是适配器模式的核心在对象适配器模式中它通过继承Target并关联一个Adaptee对象使二者产生联系。Adaptee适配者类适配者即被适配的角色它定义了一个已经存在的接口这个接口需要适配。适配者类一般是一个具体类包含了客户希望使用的业务方法在某些情况下可能没有适配者类的源代码。
代码示例
/*** 适配者类*/
public class Adaptee {public String specificRequest(String org) {return org;}
}
/*** 适配器类*/
public class Adapter extends Target{// 持有一个对象适配者类对象的引用private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee adaptee;}public String request(String org) {// 转发调用return adaptee.specificRequest(org);}
}/*** 目标抽象类*/
public class Target {public String request(String org) {return org;}}/*** 客户端*/
public class Client {public static void main(String[] args) {Target target new Target();target.request(1024);}
}2.2、类适配器模式
类适配器模式与对象适配器模式最大的区别在于其适配器和适配者之间的关系是继承关系。类适配器模式结构如下图所示。 所示的类适配器模式结构图适配器类实现了抽象目标类接口Target并继承了适配者类。在适配器类的request方法中调用所继承的适配者类的specificRequest方法实现了适配。典型的类适配器模式代码如下
/*** 适配器类*/
public class Adapter extends Adaptee implements Target {public String request(String org) {// 转发调用return super.specificRequest(org);}
}
/*** 抽象目标类接口*/
public interface Target {String request(String org);}
由于Java、C等语言不支持多重类继承因此类适配器模式的使用受到很多限制。例如如果目标抽象类Target不是接口而是一个类就无法使用类适配器模式。此外如果适配者Adaptee为最终Final类也无法使用类适配器模式。在Java等面向对象编程语言中大部分情况下使用的是对象适配器模式类适配器模式较少使用。
2.3、双向适配器模式
在对象适配器模式的使用过程中如果在适配器中同时包含对目标类和适配者类的引用适配者可以通过它调用目标类中的方法目标类也可以通过它调用适配者类中的方法那么该适配器就是一个双向适配器。其模式结构示意图如下图所示 双向适配器模式的实现较为复杂其典型代码如下
/*** 适配器类*/
public class Adapter implements Target, Adaptee {// 同时持有抽象目标类和适配者的引用private Target target;private Adaptee adaptee;public Adapter(Target target) {this.target target;}public Adapter(Adaptee adaptee) {this.adaptee adaptee;}Overridepublic String specificRequest(String org) {return adaptee.specificRequest(org);}Overridepublic String request(String org) {return target.request(org);}
}2.4、缺省适配器模式
缺省适配器模式是适配器模式的一种变体其应用也较为广泛。
缺省适配器模式的定义如下 当不需要实现一个接口所提供的所有方法时可先设计一个抽象类实现该接口并为接口中每个方法提供一个默认实现空方法那么该抽象类的子类可以选择性地覆盖父类的某些方法来实现需求。它适用于不想使用一个接口中的所有方法的情况又称为单接口适配器模式。 可以看出在缺省适配器模式中包含以下3个角色:
ServiceInterface适配者接口它是一个接口通常在该接口中声明了大量的方法。AbstractServiceClass缺省适配器类它是缺省适配器模式的核心类使用空方法的形式实现了在ServiceInterface接口中声明的方法。通常将它定义为抽象类因为对它进行实例化没有任何意义。ConcreteServiceClass具体业务类它是缺省适配器类的子类在没有引入适配器之前它需要实现适配者接口因此需要实现在适配者接口中定义的所有方法而对于一些无须使用的方法也不得不提供空实现。在有了缺省适配器模式之后可以直接继承该适配器类根据需要有选择性地覆盖在适配器类中定义的方法。
3、总结
适配器模式将现有接口转化为客户类所期望的接口实现了对现有类的复用。它是一种使用频率非常高的设计模式在软件开发中得以广泛应用在Spring等开源框架、驱动程序设计例如JDBC中的数据库驱动程序中也使用了适配器模式。
3.1、优点
将目标类和适配者类解耦。通过引入一个适配器类来重用现有的适配者类无须修改原有结构。增加了类的透明性和复用性。将具体的业务实现过程封装在适配者类中对于客户端类而言是透明的而且提高了适配者类的复用性同一个适配者类可以在多个不同的系统中复用。灵活性和扩展性都非常好。通过使用配置文件可以很方便地更换适配器也可以在不修改原有代码的基础上增加新的适配器类完全符合开闭原则。具体来说类适配器模式还有这样的优点由于适配器类是适配者类的子类因此可以在适配器类中置换一些适配者的方法使得适配器的灵活性更强。
对象适配器模式还有如下优点
1一个对象适配器可以把多个不同的适配者适配到同一个目标。
2可以适配一个适配者的子类。由于适配器和适配者之间是关联关系根据里氏代换原则适配者的子类也可通过该适配器进行适配。
3.2、缺点
对于Java、C等不支持多重类继承的语言一次最多只能适配一个适配者类不能同时适配多个适配者。适配者类不能为最终类例如在Java中不能为final类C中不能为sealed类。在Java、C等语言中类适配器模式中的目标抽象类只能为接口不能为类其使用有一定的局限性。
对象适配器模式的缺点是与类适配器模式相比要在适配器中置换适配者类的某些方法比较麻烦。如果一定要置换掉适配者类的一个或多个方法可以先做一个适配者类的子类在子类中将适配者类的方法置换掉然后再把适配者类的子类当作真正的适配者进行适配实现过程较为复杂。
4、适用场景
系统需要使用一些现有的类而这些类的接口例如方法名不符合系统的需要甚至没有这些类的源代码。想创建一个可以重复使用的类用于与一些彼此之间没有太大关联的类包括一些可能在将来引进的类一起工作。