- 浏览: 328172 次
- 性别:
- 来自: 广州
文章分类
最新评论
适配器模式把一类的接口变成客户端所期待的另一个接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作.
一:名字的由来
这很像变压器(Adapter),变压器把一种电压变成另一种电压。把美国的电器拿回中国大陆用的时候,用户就面临电压不同的问题。美国的生活用电电压是110V,而中国的电压是220V,如果要在中国使用美国的电器,就必须有一个能把220V电压转换成110V电压的变压器,而这正是本模式所做的事。
前面提到适配器模式有两种,下面一一介绍:
二:类的适配器模式
类的适配器模式把被适配的类的API转换成为目标类的API,此模式所涉及的角色有:
(A)目标(Target)角色:这就是所期待得到的接口(注:由于这里讨论的是类适配器模式,因此目标不可以是类)
(B)源(Adaptee)角色:现在需要适配的接口
(C)适配器(Adapter)角色:适配器类是本模式的核心,它把源接口转换成目标接口,显然这一角色不可以是接口,而必须是具体类
源代码如下:
由上知,Adatee类并没有sampleOperation2()方法,而客户端则期待这个方法,为使客户端能够使用Adaptee类,提供一个中间五一节,即类Adapter,把Adaptee的API与Target类的API衔接起来,Adapter与Adaptee是继承关系,这决定了这个适配器是类.
效果分析:
a.使用一个具体类把源(Adaptee)适配到目标(Target)中,这样一来,如果源以及源的子类都使用此类适配,就行不通了。
b.由于适配器类是源的子类,因此可以在适配器类中置换掉(Override)源的一些方法
c.由于只引进了一个适配器类,因此只有一个路线到达目标类,使问题得到简化.
三:对象的适配器模式
与类的适配器模式一样,对象的适配器模式把被适配的类的API转换成目标类的API,与类的适配器不同的是,对象的适配器不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类,它所需要的角色和类的适配器模式相同,下面是源代码:
请不要误认为适配器模式就是为了补充源角色没有的方法而准备的哦! !
效果分析:
a.一个适配器可以把多种不同的源适配到同一个目标,换言之,同一个适配器可以把源类和它的子类都适配到目标接口
b.与类的适配模式相比,要想置换源类的方法就不容易。如果一定要置换源类的一个或多个方法,就只好先做一个源类的子类,将源类的方法置换掉,然后再把源类的子类当做真正的源进行适配。
c.虽然要想置换源类的方法不容易,但是要想增加一些新的方法则方便得很,而且新增的方法可同时适用于所有的源.
四:在什么情况下使用适配器模式
(1)系统需要使用现有的类,而此类的接口不符合系统的需要。
(2)想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类
(3)(对对象的适配器模式而言)在设计里,需要改变多个已有的子类的接口,如果使用类的适配器模式的话,就要针对每一个子类做一个适配器类,而这不太实际.
五:利用适配器模式指方(Cube)为圆(BallIF)
上面的MagicFinger接收一个正方体,返回此正方体的内切球,本例用的是对象的适配器模式,(相对于类的适配模式)这样做的好处是,如果一旦决定不仅要支持正方体,而且要支持四面体等多面体,可以使用同一个MagicFinger类,而不必对每一个多面体建立一个MagicFinger类。
六:适配器模式在层次上的应用
(1)wine是一个免费软件,它允许用户在Linus环境里运行Window程序,可以知道,Wine提供了从Linux到Window图形界面的适配器,它使得Windows的图形界面可以在Linux界面里运行,这样不必修改任何一个图形界面,便可以使两者兼容。
(2)jdbc驱动软件
JDBC给出了一个客户端通用的界面,每一个数据库引擎的JDBC驱动软件都是一个介于JDBC接口和数据库引擎接口之间的适配器软件,如下图:
<--------------------Oracle JDBC------------Oracle
------------------
JDBC <--------------------SQLServer JDBC--------------SQLServer
------------------
<--------------------MySQL JDBC--------------MySQL
抽象的JDBC接口和各个数据库引擎的API之间都需要相应的适配器软件,即为数据库引擎准备的驱动软件.
(3)jdbc/odbc桥梁
java application-->jdbc driver manager-->jdbc/odbc bridge-->odbc driver-->DB
jdbc的库不可能和odbc的库有相同的接口,因此使用适配器模式将odbc的API接口改为jdbc的接口就是唯一可行的办法,因此jdbc/odbc bridge是适配器模式的应用.
七:模式实现的讨论
本模式需要注意的地方有:
(1)目标接口可以省略,此时目标接口和源接口实际上是相同的,由于源是一个接口,而适配器是一个类,因此这种做法看似平庸而并不平庸,它可以使客户端不必实现不需要的方法(这将在缺省适配的情况下看到)
(2)适配器类可以是抽象的(这将在缺省适配的情况下看到)
(3)带参数的适配器模式,使用这种办法,适配器可以根据参数返回一个合适的实例给客户端.
八:适配器模式和相关的模式(跳过)
一:名字的由来
这很像变压器(Adapter),变压器把一种电压变成另一种电压。把美国的电器拿回中国大陆用的时候,用户就面临电压不同的问题。美国的生活用电电压是110V,而中国的电压是220V,如果要在中国使用美国的电器,就必须有一个能把220V电压转换成110V电压的变压器,而这正是本模式所做的事。
前面提到适配器模式有两种,下面一一介绍:
二:类的适配器模式
类的适配器模式把被适配的类的API转换成为目标类的API,此模式所涉及的角色有:
(A)目标(Target)角色:这就是所期待得到的接口(注:由于这里讨论的是类适配器模式,因此目标不可以是类)
(B)源(Adaptee)角色:现在需要适配的接口
(C)适配器(Adapter)角色:适配器类是本模式的核心,它把源接口转换成目标接口,显然这一角色不可以是接口,而必须是具体类
源代码如下:
package cai.milenfan.basic.test; public interface Target { //这是源类也有的方法 void sampleOperation1(); //这是源类不有的方法 void sampleOperation2(); }
package cai.milenfan.basic.test; public class Adaptee { public void sampleOperation1(){ //....your code } }
package cai.milenfan.basic.test; public class Adapter extends Adaptee implements Target{ //由于源类没有这个方法,因此适配器类补充这个方法 public void sampleOperation2() { } }
由上知,Adatee类并没有sampleOperation2()方法,而客户端则期待这个方法,为使客户端能够使用Adaptee类,提供一个中间五一节,即类Adapter,把Adaptee的API与Target类的API衔接起来,Adapter与Adaptee是继承关系,这决定了这个适配器是类.
效果分析:
a.使用一个具体类把源(Adaptee)适配到目标(Target)中,这样一来,如果源以及源的子类都使用此类适配,就行不通了。
b.由于适配器类是源的子类,因此可以在适配器类中置换掉(Override)源的一些方法
c.由于只引进了一个适配器类,因此只有一个路线到达目标类,使问题得到简化.
三:对象的适配器模式
与类的适配器模式一样,对象的适配器模式把被适配的类的API转换成目标类的API,与类的适配器不同的是,对象的适配器不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类,它所需要的角色和类的适配器模式相同,下面是源代码:
package cai.milenfan.basic.test; public interface Target { //这是源类也有的方法 void sampleOperation1(); //这是源类不有的方法 void sampleOperation2(); }
package cai.milenfan.basic.test; public class Adaptee { public void sampleOperation1(){ //....your code } }
package cai.milenfan.basic.test; public class Adapter implements Target{ private Adaptee adaptee; public Adapter(Adaptee adaptee){ super(); this.adaptee = adaptee; } //源类有方法,适配器直接委派即可 public void sampleOperation1() { adaptee.sampleOperation1(); } //源类没有这个方法,因此适配器类需要补充此方法 public void sampleOperation2() { //write your code here..... } }
请不要误认为适配器模式就是为了补充源角色没有的方法而准备的哦! !
效果分析:
a.一个适配器可以把多种不同的源适配到同一个目标,换言之,同一个适配器可以把源类和它的子类都适配到目标接口
b.与类的适配模式相比,要想置换源类的方法就不容易。如果一定要置换源类的一个或多个方法,就只好先做一个源类的子类,将源类的方法置换掉,然后再把源类的子类当做真正的源进行适配。
c.虽然要想置换源类的方法不容易,但是要想增加一些新的方法则方便得很,而且新增的方法可同时适用于所有的源.
四:在什么情况下使用适配器模式
(1)系统需要使用现有的类,而此类的接口不符合系统的需要。
(2)想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类
(3)(对对象的适配器模式而言)在设计里,需要改变多个已有的子类的接口,如果使用类的适配器模式的话,就要针对每一个子类做一个适配器类,而这不太实际.
五:利用适配器模式指方(Cube)为圆(BallIF)
package cai.milenfan.basic.test; public class Cube { private double width; public Cube(double width){ this.width = width; } //计算体积 public double calculateVolume(){ return width*width*width; } //计算面积 public double calculateFaceArea(){ return width*width; } public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } }
package cai.milenfan.basic.test; public interface BallIF { //计算面积 double calculateArae(); //计算体积 double calculateVolume(); //半径的get/set double getRadius(); void setRadius(double radius); }
package cai.milenfan.basic.test; public class MagicFinger implements BallIF{ private double radius = 0; private static final double PI = 3.14d; private Cube adaptee; public MagicFinger(Cube adaptee){ super(); this.adaptee = adaptee; radius = adaptee.getWidth(); } public double calculateArae() { return PI * 4.0d * (radius * radius); } public double calculateVolume() { return PI * 4.0d/3.0d * (radius * radius * radius); } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } }
上面的MagicFinger接收一个正方体,返回此正方体的内切球,本例用的是对象的适配器模式,(相对于类的适配模式)这样做的好处是,如果一旦决定不仅要支持正方体,而且要支持四面体等多面体,可以使用同一个MagicFinger类,而不必对每一个多面体建立一个MagicFinger类。
六:适配器模式在层次上的应用
(1)wine是一个免费软件,它允许用户在Linus环境里运行Window程序,可以知道,Wine提供了从Linux到Window图形界面的适配器,它使得Windows的图形界面可以在Linux界面里运行,这样不必修改任何一个图形界面,便可以使两者兼容。
(2)jdbc驱动软件
JDBC给出了一个客户端通用的界面,每一个数据库引擎的JDBC驱动软件都是一个介于JDBC接口和数据库引擎接口之间的适配器软件,如下图:
<--------------------Oracle JDBC------------Oracle
------------------
JDBC <--------------------SQLServer JDBC--------------SQLServer
------------------
<--------------------MySQL JDBC--------------MySQL
抽象的JDBC接口和各个数据库引擎的API之间都需要相应的适配器软件,即为数据库引擎准备的驱动软件.
(3)jdbc/odbc桥梁
java application-->jdbc driver manager-->jdbc/odbc bridge-->odbc driver-->DB
jdbc的库不可能和odbc的库有相同的接口,因此使用适配器模式将odbc的API接口改为jdbc的接口就是唯一可行的办法,因此jdbc/odbc bridge是适配器模式的应用.
七:模式实现的讨论
本模式需要注意的地方有:
(1)目标接口可以省略,此时目标接口和源接口实际上是相同的,由于源是一个接口,而适配器是一个类,因此这种做法看似平庸而并不平庸,它可以使客户端不必实现不需要的方法(这将在缺省适配的情况下看到)
(2)适配器类可以是抽象的(这将在缺省适配的情况下看到)
(3)带参数的适配器模式,使用这种办法,适配器可以根据参数返回一个合适的实例给客户端.
八:适配器模式和相关的模式(跳过)
发表评论
-
Mina重连
2014-05-26 21:29 2865import com.sun.swing.internal. ... -
面试经典
2014-05-24 09:29 6081.mysql innodb引擎,什么叫聚集索引,与非聚集索 ... -
一拍网网站系统架构图
2014-03-28 21:24 539一拍网网站系统架构图 -
Window下安装配置nginx
2013-08-12 16:53 736安装:http://www.cnblogs.com/wen ... -
使用线程池的好处
2013-07-18 14:41 1143使用线程池有两个好处: 1.可以创建和销毁线程所带来的系统 ... -
Java ThreadLocal使用浅析
2013-07-18 14:36 415ThreadLocal通过在其内部保存变量的副本,并且各个副本 ... -
MyBatis学习之简单增删改查操作、MyBatis存储过程、MyBatis分页、MyBatis一对一、MyBatis一对多
2013-07-05 13:06 1092http://blog.csdn.net/zhangwei ... -
分享一位网友的架构杂谈
2013-05-20 23:16 873不容类型的网站,并发处理不一样,例如针对sns这种类型的网站 ... -
JSP页面静态化
2013-04-08 09:20 805http://www.java-zone.org/644.ht ... -
Java compile to C++
2013-03-19 14:53 465http://code.google.com/a/eclips ... -
几个TCP Socket的通信框架
2013-03-19 12:26 947http://www.oschina.net/p/simple ... -
宝贝鱼
2013-03-18 23:54 638http://code.google.com/p/cshbbr ... -
将Java程序注册成系统服务(NT服务)
2013-03-16 16:14 571http://blog.csdn.net/small____f ... -
Java内存回收机制
2013-03-13 15:47 782http://www.iteye.com/blogs/tag/ ... -
支付宝,百付宝集成
2013-03-13 14:01 898http://help.alipay.com/support/ ... -
SSH+EXTJS项目下载
2013-03-11 23:02 387http://download.csdn.net/tag/Ex ... -
Hibernate中使用Threadlocal创建线程安全的Session
2013-03-04 20:39 490http://blog.sina.com.cn/s/blog_ ... -
Java Socket多线程通信
2012-10-09 09:53 811当Server没接受到一个Client连接请求之后,都把处理流 ... -
Java 多线程的一个例子
2012-10-09 09:48 984目录: 1 synchronized的 ... -
app引擎
2012-07-10 09:39 0http://sae.sina.com.cn/ htt ...
相关推荐
实验七:适配器模式.rar实验七:适配器模式.rar
为三类: 类适配器模式、 对象适配器模式、 接口适配器模式。 以生活中手机充电为例来讲解适配器模式, 手机本身并不能直接用220V交流电, 需要将220V的交流电转换为5V的直流电, 在这个过程 中, 充电器本身相当于...
NULL 博文链接:https://364232252.iteye.com/blog/2370693
第十六讲:适配器模式 第十七讲:解释器模式 第十八讲:中介者模式 第十九讲:职责链模式 第二十讲:迭代模式 第二十一讲:模板方法模式 第二十二讲:备忘录模式 第二十三讲:访问者模式 第二十四讲:状态...
设计模式之适配器模式Java版 设计模式之适配器模式Java版 设计模式之适配器模式Java版 设计模式之适配器模式Java版
软件体系结构实验报告
适配器模式的Java实现版本,包含类适配器模式和对象适配器模式的实现,同时也包含两者的UML类图
java设计模式【之】适配器模式【源码】【场景:水和容器】 * 适配器模式,类似(亡羊补牢) * 已经存在的类(功能已经开发完成了),与新需求的功能相似,但是略有差异 * 当已经存在的方法无法满足现有需求,需要...
C#设计模式之适配器模式应用实例
适配器模式是一种结构型设计模式,它允许接口不兼容的两个类可以协同工作。以下是该模式的要点: 1. **角色**: - **Target(目标接口)**:客户端期望调用的接口。 - **Adaptee(适配者)**:现有的、接口与目标...
.NET设计模式(8):适配器模式(AdapterPattern)
java设计模式之适配器模式,希望对大家有所帮助。
适配器模式代码demo 适配器模式代码demo 适配器模式代码demo
动态代理模式 适配器模式 实现,都可以运行,有一部分注解
C#面向对象设计模式纵横谈(7):Adapter 适配器模式(结构型模式) 体验课程
[刚刚上传的demo运行有问题,重新传了个新的],这个的一个iOS的适配器模式的实例代码,目前就是一个简单的demo,后期还会更新适配器在 MVC,MVP,MVVM中的使用,demo对应着简书:https://www.jianshu.com/p/e2ebcf19098f,...
Java设计模式之适配器模式
designPattern3设计模式3:适配器模式,篮球翻译适配器,游戏存进度,备忘录模式基本代码,游戏进度备忘