一、认识适配器模式
目的:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的类能够一起工作。
适配器模式分为两种:类适配器模式、对象适配器模式,通常我们使用后者。
类适配器模式:对应适配器继承适配者,由于Java是单继承所以一般不使用类适配器模式会具有局限性。
优点:由于适配器类是适配者类的子类,因此可以再适配器类中置换一些适配者的方法,使得适配器的灵活性更强。
缺点:对于Java、C#等不支持多重继承的语言,一次最多只能适配一个适配者类,而且目标抽象类只能为接口,不能为类,其使用有一定的局限性,不能将一个适配者类和他的子类同时适配到目标接口。
对象适配器模式:在适配器的构造器中添加适配者的参数,在使用适配器时传入适配者,就能够做到灵活使用。
优点:把多个不同的适配者适配到同一个目标,也就是说,同一个适配器可以把适配者类和他的子类都适配到目标接口。
缺点:与类适配器模式相比,要想置换适配者类的方法就不容易。
总体优缺点:
优点:通过适配器能够透明的调用目标接口;复用现存的类,程序员不需要修改原有代码而重用现在的适配者,在许多业务中符合开闭原则。
缺点:适配器编写过程中需要结合业务场景来考虑,会增加系统的复杂性;增加代码阅读难度,降低代码可读性。
包含角色:目标接口、适配者类、适配器类。
应用场景:
以前开发的系统存在满足新系统功能需求的类,但其接口同新系统的接口不一致。
使用第三方提供的组件,但组件接口定义和自己要求的接口定义不同。
UML图如下:分别是继承(类适配器)与组合(对象适配器)的关系
二、实现适配器模式
2.1、类适配器与对象适配器模式
见adapter目录下代码:
需求说明:现在我有个电脑,有一个网线,但是电脑上的网线口与现在网线口不一致,此时我们需要一个适配器,通过使用适配器来连接网线实现上网!
适配者(网线):Reticle
//网线 public class Reticle { public void request(){ System.out.println("插上网线上网"); } }
适配器接口:NetToUSB
//适配器接口 public interface NetToUSB { //作用:处理请求 将网线=>USB void handleRequest(); }
使用者(电脑):Computer
public class Computer { //进行上网 public void net(NetToUSB adapter){ //调用适配器的方法 adapter.handleRequest(); } }
通过传入适配器(可以说接上)就能够使用网线了,使用网线的具体操作交由适配器完成。
现在就差一个具体适配器了,有了适配器我们就能够上网!!!
类适配器模式
具体适配器:Adapter
//类适配器实现 public class Adapter extends Reticle implements NetToUSB{ @Override public void handleRequest() { super.request(); } }
实现适配器接口,并且继承网线,在实现方法中调用网线的连接操作。
测试代码:测试类Customer
public class Customer { //①测试继承方式的适配器 public static void main(String[] args) { Computer computer = new Computer();//电脑 Reticle reticle = new Reticle();//网线 NetToUSB adapter = new Adapter();//适配器 computer.net(adapter); }
问题说明:该适配器通过继承网线的方式来进行调用方法,这种就有弊端了,若是下次需要适配不同的连接线岂不是需要添加其他的适配器类(实现适配器接口)嘛,这样的话系统会变得更加复杂了。由于Java中是单继承,所以这个适配器仅仅只能服务于所继承的适配者。
对象适配器模式
具体适配器:Adapter2
//对象适配器实现 public class Adapter2 implements NetToUSB{ private Reticle reticle; //传入指定的适配者 public Adapter2(Reticle reticle){ this.reticle = reticle; } @Override public void handleRequest() { reticle.request(); } }
对象适配器的话就是传入指定的适配者,在适配方法中调用适配者的方法即可!
测试代码:测试类Customer
//②测试组合方式的适配器 @Test public void test01(){ Computer computer = new Computer();//电脑 Reticle reticle = new Reticle();//网线 //将网线传入到适配器中(组合方式) NetToUSB adapter = new Adapter2(reticle); computer.net(adapter); }
说明:通过使用对象适配器,能够将多个不同的适配者适配到同一个目标,也就是说,同一个适配器可以把适配者类和他的子类都适配到目标接口。
总结
1、通过使用适配器模式能够将一些原来老系统的接口通过适配器来使用到我们的新系统上去,类似于我们生活中的转接器。
2、适配器模式有两种方式:类适配器模式(适配器继承适配者方式)、对象适配器模式(适配器组合适配者方式)。建议使用对象适配器模式