设计模式之适配器模式
前言
适配器模式(Adapter)的定义如下:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。适配器模式分为类结构型模式和对象结构型模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。
提示:以下是本篇文章正文内容,下面案例可供参考
一、适配器是什么?
想了解适配器是什么,要了解适配器的组成,适配器模式(Adapter)包含以下主要角色。
目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。
这就是适配器的几种角色,将不同角色功能衔接就能整合成一个流程。当然了适配得先有适配的对象,通过从配置中加载,或者其他途径获得。我们看一下一个案例。
在 Spring 的 Aop 中,适配器模式应用的非常广泛。Spring 使用 Advice(通知)来增强被代理类的功能,Advice 的类型主要有 BeforeAdvice、AfterReturningAdvice、ThrowsAdvice。每种 Advice 都有对应的拦截器。各种不同类型的 Interceptor,通过适配器统一对外提供接口,如下类图所示:client —> target —> adapter —> interceptor —> advice。最终调用不同的 advice来实现被代理类的增强。
Spring 会根据不同的 AOP 配置来确定使用对应的 Advice。这就是客户的目标,那么走这个流程即可。
二、使用步骤
1.适配器
1.类适配器
类适配器适配的是类
2.对象适配器
对象适配器适配的是对象
类与对象适配器的区别:对象适配器通过委派与adaptee衔接,即持有adaptee对象,是动态的方式;类适配器通过集成与adaptee衔接,也就是说类适配器继承adaptee,并且实现target方法,是静态的方式。
现在我们可以分析一下类适配器代码:
//目标接口
interface Target
{
public void request();
}
//适配者接口
class Adaptee
{
public void specificRequest()
{
System.out.println("适配者中的业务代码被调用!");
}
}
//类适配器类
class ClassAdapter extends Adaptee implements Target
{
public void request()
{
specificRequest();
}
}
类适配器类实现了目标接口,继承了适配器接口
//客户端代码
public class ClassAdapterTest
{
public static void main(String[] args)
{
System.out.println("类适配器模式测试:");
Target target = new ClassAdapter();
target.request();
}
}
上文中说到,只是持有对象,不是实现也不是继承,只是集成衔接,对象是可以动态变化的。
//对象适配器类
class ObjectAdapter implements Target{
private Adaptee adaptee;
public ObjectAdapter(Adaptee adaptee) {
this.adaptee=adaptee;
}
public void request(){
adaptee.specificRequest();
}
}
//客户端代码
public class ObjectAdapterTest{
public static void main(String[] args) {
System.out.println("对象适配器模式测试:");
Adaptee adaptee = new Adaptee();
Target target = new ObjectAdapter(adaptee);
target.request();
}
}
2.案例
1.创建适配器类
//目标:发动机
interface Motor
{
public void drive();
}
//适配者1:电能发动机
class ElectricMotor
{
public void electricDrive()
{
System.out.println("电能发动机驱动汽车!");
}
}
//适配者2:光能发动机
class OpticalMotor
{
public void opticalDrive()
{
System.out.println("光能发动机驱动汽车!");
}
}
//电能适配器
class ElectricAdapter implements Motor
{
private ElectricMotor emotor;
public ElectricAdapter()
{
emotor=new ElectricMotor();
}
public void drive()
{
emotor.electricDrive();
}
}
//光能适配器
class OpticalAdapter implements Motor
{
private OpticalMotor omotor;
public OpticalAdapter()
{
omotor=new OpticalMotor();
}
public void drive()
{
omotor.opticalDrive();
}
}
//客户端代码
public class MotorAdapterTest
{
public static void main(String[] args)
{
System.out.println("适配器模式测试:");
Motor motor=(Motor)ReadXML.getObject();
motor.drive();
}
}
2.测试
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
class ReadXML
{
public static Object getObject()
{
try
{
DocumentBuilderFactory dFactory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=dFactory.newDocumentBuilder();
Document doc;
doc=builder.parse(new File("src/adapter/config.xml"));
NodeList nl=doc.getElementsByTagName("className");
Node classNode=nl.item(0).getFirstChild();
String cName="adapter."+classNode.getNodeValue();
Class<?> c=Class.forName(cName);
Object obj=c.newInstance();
return obj;
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
}
从测试中可以看出加载了config.xml中的对象,我们适配的是光能发动机和电能发电机两种,配置不同,输出也不同,所以说,适配的依据是配置文件里面的配置。