设设计模型之适配器模式
1.适配器模式
1.1 定义与特点
适配器模式(Adapter)的定义如下:使用一个已经存在的类,而他的接口不符合我们的需求。这个时候我们本着开闭原则,要创建一个既符合我们需求(加入独立的或不兼容的接口功能)又实现了已存在的接口的类。适配器模式分为类结构型模式和对象结构型模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。
该模式的主要优点如下:
- 客户端通过适配器可以透明地调用目标接口。
- 复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类。
- 将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题。
其缺点是:对类适配器来说,更换适配器的实现过程比较复杂。
1.2 模式的结构
适配器模式(Adapter)包含以下主要角色。
- 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
- 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。
- 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。
1.3 UML类图
1.4 问题由来
在现实生活中,经常出现两个对象因接口不兼容而不能在一起工作的实例,这时需要第三者进行适配。例如,用直流电的笔记本电脑接交流电源时需要一个电源适配器,用计算机访问照相机的 SD 内存卡时需要一个读卡器等。
在软件设计中也可能出现:需要开发的具有某种业务功能的组件在现有的组件库中已经存在,但它们与当前系统的接口规范不兼容,如果重新开发这些组件成本又很高,这时用适配器模式能很好地解决这些问题
1.5 解决思路
有两种方式解决,第一种就是类适配器模式,主要的思想就是靠继承来实现适配,即在原有的组件基础上继承新业务功能类,第二种就是对象适配器模式,主要思想是将新业务功能类的对象注入到原有的组件中,然后达到适配的作用
1.6 解决方案
1.类适配器模式
/**
* @author 26530
* HDMI接口
*/
public interface HDMIPort
{
void useHDMIPort();
}
/**
* @author 26530
* 数据转换线
*/
public class DataConversionLine
{
public void vgaToHdmi()
{
System.out.println("将VGA数据传输转为HDMI");
}
}
/**
* @author 26530
* 笔记本电脑
*/
public class LaptopComputer extends DataConversionLine implements HDMIPort
{
@Override
public void useHDMIPort()
{
System.out.println("使用的HDMI接口");
}
}
/**
* @author 26530
* 投影仪
*/
public class Projector
{
public void dataLine()
{
System.out.println("投影仪使用的是VGA接口的数据线");
}
}
public class Test
{
public static void main(String[] args)
{
//笔记本想连接投影仪,但是笔记本自身的接口是HDMI,投影仪的接口是VGA的。
//为解决这个问题,我们需要一个适配器,把vga的接口转为hdmi,通过这个适配器就可以实现笔记本电脑和投影仪连接了
Projector projector = new Projector();
projector.dataLine();
LaptopComputer laptopComputer = new LaptopComputer();
laptopComputer.vgaToHdmi();
laptopComputer.useHDMIPort();
/*
投影仪使用的是VGA接口的数据线
将VGA数据传输转为HDMI
使用的HDMI接口
*/
//这样就实现了笔记本和投影仪相连接
}
}
2.对象适配器模式
/**
* @author 26530
* HDMI接口
*/
public interface HDMIPort
{
void useHDMIPort();
}
/**
* @author 26530
* 数据转换线
*/
public class DataConversionLine
{
public void vgaToHdmi()
{
System.out.println("将VGA数据传输转为HDMI");
}
}
/**
* @author 26530
* 笔记本电脑
*/
public class LaptopComputer implements HDMIPort
{
private DataConversionLine dataConversionLine;
public LaptopComputer(DataConversionLine dataConversionLine) {
super();
this.dataConversionLine = dataConversionLine;
}
public LaptopComputer() {
super();
// TODO Auto-generated constructor stub
}
@Override
public void useHDMIPort()
{
System.out.println("使用的HDMI接口");
}
public DataConversionLine getDataConversionLine() {
return dataConversionLine;
}
public void setDataConversionLine(DataConversionLine dataConversionLine) {
this.dataConversionLine = dataConversionLine;
}
}
/**
* @author 26530
* 投影仪
*/
public class Projector
{
public void dataLine()
{
System.out.println("投影仪使用的是VGA接口的数据线");
}
}
public class Test
{
public static void main(String[] args)
{
//笔记本想连接投影仪,但是笔记本自身的接口是HDMI,投影仪的接口是VGA的。
//为解决这个问题,我们需要一个适配器,把vga的接口转为hdmi,通过这个适配器就可以实现笔记本电脑和投影仪连接了
Projector projector = new Projector();
projector.dataLine();
DataConversionLine dataConversionLine = new DataConversionLine();
LaptopComputer laptopComputer = new LaptopComputer(dataConversionLine);
laptopComputer.getDataConversionLine().vgaToHdmi();
laptopComputer.useHDMIPort();
/*
投影仪使用的是VGA接口的数据线
将VGA数据传输转为HDMI
使用的HDMI接口
*/
//这样就实现了笔记本和投影仪相连接
}
}