前言
参考:http://c.biancheng.net/view/1...
- 在现实生活中,经常出现两个对象因接口不兼容而不能在一起工作的实例,这时需要第三者进行适配。例如,讲中文的人同讲英文的人对话时需要一个翻译,用直流电的笔记本电脑接交流电源时需要一个电源适配器,用计算机访问照相机的 SD 内存卡时需要一个读卡器等。
- 在软件设计中也可能出现:需要开发的具有某种业务功能的组件在现有的组件库中已经存在,但它们与当前系统的接口规范不兼容,如果重新开发这些组件成本又很高,这时用适配器模式能很好地解决这些问题。
内容
1.模式定义与特点
适配器模式(Adapter)的定义如下:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。适配器模式分为类结构型模式和对象结构型模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。
该模式的主要优点如下。
- 客户端通过适配器可以透明地调用目标接口。
- 复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类。
- 将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题。
其缺点是:对类适配器来说,更换适配器的实现过程比较复杂。
2.模式的结构
类适配器模式可采用多重继承方式实现,如C++可定义一个适配器类来同时继承当前系统的业务接口和现有组件库中已经存在的组件接口;Java不支持多继承,但可以定义一个适配器类来实现当前系统的业务接口,同时又继承现有组件库中已经存在的组件。
模式的结构:
适配器模式(Adapter)包含以下主要角色。
- 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
- 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。
- 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。
3.模式的实例
3.1 场景介绍
场景介绍:
(1)假设我们做了一个第一版的一个系统,这个系统里有一个接口和一个实现类
(2)接着我们开始做第二版的系统,这个系统我们定义了一个新的接口,和新的实现类
(3)但是我们同时在第二版的系统中,也要使用第一版系统中定义的那个老接口和老实现类
3.2 不用设计模式实现
public class NonPatternApplication {
public static void main(String[] args) {
OldInterface oldInterface = new OldInterfaceImpl();
NewInterface newInterface = new NewInterfaceImpl();
oldInterface.oldRun();
newInterface.newRun();
/**
* 如果不使用任何涉及模式,我们的问题在哪?
* 问题其实很显然,就是说,我们的新代码中,面向的是规范和风格完全不同的两套接口,你理解和维护的成本提高了
* 其次,假如说,现在都不给你选择使用老版本接口的机会
* 直接强制性公司规范要求按照新版本接口来走,你的老版本接口的实现类,就没法用了啊?
* 难不成还要基于新版本的接口重新写一套?
*/
}
//===============接口====================
// 老版本接口
public static interface OldInterface{
void oldRun();
}
//新版本接口
public static interface NewInterface{
void newRun();
}
//================实现类====================
public static class OldInterfaceImpl implements OldInterface{
public void oldRun() {
System.out.println("老版本功能逻辑");
}
}
public static class NewInterfaceImpl implements NewInterface{
public void newRun() {
System.out.println("新版本功能逻辑");
}
}
}
3.3 适配器模式实现
public class AdapterPatternApplication {
public static void main(String[] args) {
NewInterface oldInterface = new NewInterfaceAdapter(new OldInterfaceImpl());
NewInterface newInterface = new NewInterfaceImpl();
//适配器里面实现的是新接口,但是真实调用是老街口的实现类和方法
oldInterface.newRun();
newInterface.newRun();
// 适配器模式
// 就是你手上有新老俩接口和一个老接口的实现类
// 但是现在系统中要面向新接口来开发,老接口的实现类就不能直接用了,不能直接面向老接口来开发
// 开发一个老接口到新接口的一个适配器
// 适配器是"实现了新接口的",但是适配器中持有"老接口实现类实例的引用"
// 适配器的新接口方法的实现,全部基于"老接口实现类的老方法"来实现即可
// 对于调用方而言,只要使用适配器来开发即可,就可以通过面向新接口开发,底层使用老接口实现类
}
//===============适配器===================
public static class NewInterfaceAdapter implements NewInterface{
private OldInterface oldInterface;
public NewInterfaceAdapter(OldInterface oldInterface){
this.oldInterface = oldInterface;
}
public void newRun() {
oldInterface.oldRun();
}
}
//===============接口====================
// 老版本接口
public static interface OldInterface{
void oldRun();
}
//新版本接口
public static interface NewInterface{
void newRun();
}
//================实现类====================
public static class OldInterfaceImpl implements OldInterface {
public void oldRun() {
System.out.println("老版本功能逻辑");
}
}
public static class NewInterfaceImpl implements NewInterface {
public void newRun() {
System.out.println("新版本功能逻辑");
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。