在计算机编程中,适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。
适配器分为两种:
1.类适配器
2.对象适配器
类适配器
1.创建一个被适配的类
//已存在的、具有特殊功能、但不符合我们既有的标准接口的类 public class Adaptee { public void specificRequest(){ System.out.println("被适配的类 具有特殊功能"); } }
2.创建一个普通接口和实现类
//适配接口 public interface Target { //普通接口方法 public void request(); }
//具体目标类,只提供普通功能 public class ConcreteTarget implements Target{ @Override public void request() { // TODO Auto-generated method stub System.out.println("普通类 不具有特殊功能"); } }
3.创建适配器类对象
//适配器类,继承了被适配类,同时实现标准接口 public class Adapter extends Adaptee implements Target{ //实现方法 @Override public void request() { //调用父类的方法实现功能 super.specificRequest(); } }
4.测试类
//测试类 public class Client { public static void main(String[] args) { //使用普通类功能 Target target=new ConcreteTarget(); target.request(); //特殊类,具有特殊功能 Target target2=new Adapter(); target2.request(); } }
测试结果
上面这种实现的适配器称为类适配器,因为 Adapter 类既继承了 Adaptee (被适配类),也实现了 Target 接口(因为 Java 不支持多继承,所以这样来实现),在 Client 类中我们可以根据需要选择并创建任一种符合需求的子类,来实现具体功能。
对象适配器
对象适配器不是使用多继承或继承再实现的方式,而是使用直接关联,或者称为委托的方式
1.适配器类
//适配器类,实现标准接口 public class Adapter implements Target{ //注入要适配的对象 private Adaptee adaptee; //重写带参构造 public Adapter(Adaptee adaptee){ this.adaptee=adaptee; } //实现方法 @Override public void request() { //调用父类的方法实现功能 adaptee.specificRequest(); } }
2.测试类
//测试类 public class Client { public static void main(String[] args) { //使用普通类功能 Target target=new ConcreteTarget(); target.request(); //特殊类,具有特殊功能 Target target2=new Adapter(new Adaptee()); target2.request(); } }
小结
测试结果与上面的一致。从类图中我们也知道需要修改的只不过就是 Adapter 类的内部结构,即 Adapter 自身必须先拥有一个被适配类的对象,再把具体的特殊功能委托给这个对象来实现。使用对象适配器模式,可以使得 Adapter 类(适配类)根据传入的 Adaptee 对象达到适配多个不同被适配类的功能,当然,此时我们可以为多个被适配类提取出一个接口或抽象类。这样看起来的话,似乎对象适配器模式更加灵活一点。