结构型模式可以描述两种不同的东西---类和类的实例(即对象)。
1.适配器模式(Adapter Pattern):将一个类的接口转换成客户希望的另一个接口,适配器模式让那些接口不兼容的类可以一起工作。
适配器包含以下三个角色。
(1)Target(目标抽象类):目标抽象类定义客户所需的接口,可以是一个抽象类或者接口,也可以是一个具体类。在适配器中,由于Java语言不支持多重继承,它只能是接口。
(2)Adapter(适配器类):它可以调用另一个接口,作为一个转换器,对Aadptee和Target进行适配。适配器Adapter是适配器模式的核心,在类适配器中,它通过继承Target并关联一个Adaptee对象使二者产生联系。
(3)Adaptee(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类一般是一个具体类,包含了客户希望使用的业务方法,在某些情况下甚至没有适配者类的源代码。
/**典型的类适配器模式*/
public class Adapter extend Adaptee implements Target{
public void request(){
super.specificRequest();
}
}
/**典型的对象适配器*/
public class Adapter extends Target{
private Adaptee adaptee;//维持一个对适配器对象的引用
public Adapter(Adapter adapter){
this.adapter = adapter;
}
public void request(){
adaptee.specificRequest();//转发调用
}
}
在实际开发中对象适配器使用的更多一点。
2.适配器模式实例:一家软件公司想要新设计一个图片处理工具,但是之前已经开发了图片上色和剪裁的功能,现在已经设计除了图片复制的功能。为了复用代码,所以设计一个图片控制器接口,并将需求方法在这里定义,然后再设计图片适配器,将原来上色和剪裁(适配者)功能适配。
/**图片控制类,充当目标抽象类*/
public abstract class PictureControl {
public static String TAG = "Adapter";
public void copy(){
System.out.println("对图片进行复制");
}
public abstract void cut();//剪切图片
public abstract void color();//图片上色
}
/**裁剪类,充当适配者*/
public class PictureCut {
public void alarmCut(){
System.out.println("对图片进行剪裁");
}
}
/**颜色类,充当适配者*/
public class PictureColor {
public void alarmColor(){
System.out.println("对图片进行上色");
}
}
/**图片适配器,充当适配器*/
public class PictureAdapter extends PictureControl {
private PictureColor color;//定义适配者PictureColor对象
private PictureCut cut;//定义适配者PictureCut对象
public PictureAdapter(){
color = new PictureColor();
cut = new PictureCut();
}
//对图片进行剪辑
public void cut(){
cut.alarmCut();//调用适配者类PictureCut的方法
}
//对图片进行上色
public void color(){
color.alarmColor();//调用适配者类PictureColor的方法
}
}
配置文件config.xml,在配置文件中存储了适配器类的类名(注:这是反射机制,如果直接在客户端new一个对象实例,可以不用下面的方法。)
<?xml version="1.0"?>
<config>
<className>designpatterns.adapter.PictureAdapter</className>
</config>
XML.Util工具类
public class XMLUtil{
//该方法用于从XML配置文件中提取具体类的类名,并返回一个实例对象
public static Object getBean(){
try{
//创建DOM文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("src//designpatterns//adapter//config.xml"));
//获取包含类名的文本节点
NodeList nl = doc.getElementsByTagName("className");
Node classNode = nl.item(0).getFirstChild();
String cName = classNode.getNodeValue();
//通过类名生成实例对象并将其返回
Class c = Class.forName(cName);
Object obj = c.newInstance();
return obj;
}
catch(Exception e){
e.printStackTrace();
return null;
}
}
}
客户端测试类
public class Client{
public static void main(String args[]){
PictureController picture;
//picture = (CarController)XMLUtil.getBean();//反射机制,用上面的XML和XMLUtil工具类实现
picture = new PictureAdapter();
picture.copy();
picture.cut();
picture.color();
}
}
3.代码运行结果: