Java 适配器(Adapter)模式
一、什么是适配器模式:
把一个接口变成另外一个接口,使得原本因接口不匹配无法一起工作的两个类一起工作。
二、适配器模式的分类和结构:
适配器模式有类的适配器模式和对象的适配器模式两种。
1、类的适配器模式:
有时候为了使用现有的类,但是此类接口不符合需求时,需要将一个类的接口与其他类的接口进行组合,达到我们的使用需求。类的的适配器模式就是把被适配的类的API转换成目标类的API,静态结构图如下图所示:
Target希望即使用sampieOperation1()又使用sampieOperation2(),但是很显然Adaptee并不满足要求,现在只能通过一个中间环节Adapter,继承Adaptee类,提供一个sampieOperation2()方法,满足客户端的需求,达到Target的效果。
(1)Target(目标抽象类):所期待的接口。注意,类的适配器模式中,目标不可以是类,而是接口。
(2)Adapter(适配器类):模式的核心类,将原接口转换成目标接口,必须是具体类。
(3)Adaptee(适配者类):需要适配的接口。
(4)Client(客户类):针对目标抽象类编程,调用其定义的方法。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * 达到客户端要求的目标角色 3 * 4 * @author:Zhou_DX 5 * @sine: 2019年3月25日 下午7:57:05 6 * @Description: 7 */ 8 public interface TargetClass { 9 /** 10 * 下单(源类中有的方法) 11 */ 12 public void downloaOrder(); 13 14 /** 15 * 发货(源类中没有的方法) 16 */ 17 public void send(); 18 19 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * 源适配器 3 * 4 * @author:Zhou_DX 5 * @sine: 2019年3月25日 下午8:00:59 6 * @Description: 7 */ 8 public class AdapteeClass { 9 /** 10 * 下单(源类中有的方法) 11 */ 12 public void downloaOrder() { 13 System.out.println("下载订单"); 14 } 15 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * 类的适配器 3 * 4 * @author:Zhou_DX 5 * @sine: 2019年3月25日 下午8:02:43 6 * @Description: 7 */ 8 public class AdapterClass extends AdapteeClass implements TargetClass { 9 /** 10 * 发货 11 */ 12 @Override 13 public void send() { 14 // TODO Auto-generated method stub 15 System.out.println("发货"); 16 } 17 }
2.对象适配器模式:
同样的,对象适配器也是将一个类的API转换成我们所期待的API,不同的是,类的适配器中,通过继承得到目标类,而对象适配器则是通过封装,在Adapter中封装Adaptee的一个对象,将Target与Adaptee连接起来。结构如图所示:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * 达到客户端要求的目标角色 3 * 4 * @author:Zhou_DX 5 * @sine: 2019年3月25日 下午7:57:05 6 * @Description: 7 */ 8 public interface TargetObject { 9 /** 10 * 下单(源类中有的方法) 11 */ 12 public void downloaOrder(); 13 14 /** 15 * 发货(源类中没有的方法) 16 */ 17 public void send(); 18 19 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * 源适配器 3 * 4 * @author:Zhou_DX 5 * @sine: 2019年3月25日 下午8:00:59 6 * @Description: 7 */ 8 public class AdapteeObject { 9 /** 10 * 下单(源类中有的方法) 11 */ 12 public void downloaOrder() { 13 System.out.println("下载订单"); 14 } 15 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * 类的适配器 3 * 4 * @author:Zhou_DX 5 * @sine: 2019年3月25日 下午8:02:43 6 * @Description: 7 */ 8 public class AdapterObject implements TargetObject { 9 private AdapteeObject adapter_class; 10 11 public AdapterObject(AdapteeObject adapteeClass) { 12 super(); 13 this.adapter_class = adapteeClass; 14 15 } 16 17 /** 18 * 发货 19 */ 20 @Override 21 public void send() { 22 // TODO Auto-generated method stub 23 System.out.println("发货"); 24 } 25 26 /* 27 * (non-Javadoc) 28 * 29 * @see adapter_object.TargetClass#downloaOrder() 30 */ 31 @Override 32 public void downloaOrder() { 33 // TODO Auto-generated method stub 34 adapter_class.downloaOrder(); 35 } 36 }
对象适配器的优点:
同一个适配器可以将源和它的子类都适配到目标接口。
三、类适配器和对象适配器的比较:
类适配器中,适配器类通过实现Target接口并继承Adaptee类,实现适配目的。
1 public class Adapter extends Adaptee implements Target 2 { 3 //request()方法为Target接口里所定义的方法 4 public void request() 5 { 6 specificRequest();//该方法为Adaptee类里定义的方法 7 } 8 }
对象适配器中,适配器类通过继承Target类并关联一个Adaptee对象,实现适配目的。
1 public class Adapter extends Target 2 { 3 private Adaptee adaptee;//所关联的适配者类的对象 4 public Adapter(Adaptee adaptee) 5 { 6 this.adaptee=adaptee; 7 } 8 public void request() 9 { 10 adaptee.specificRequest(); 11 } 12 }