在阎宏博士的《JAVA与模式》一书中开头是这样描述适配器(Adapter)模式的:

  适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。

  作用

  类似于三相插头到两相插头转换器(适配器)所起的作用。

  结构

  适配器模式有类的适配器模式和对象的适配器模式这两种不同的形式。

  类适配器模式

  把适配类的API转换成目标类的API,见下图:

  

  Adaptee类没有sampleOperation2方法,而客户端需要使用这个方法。Adapter类继承了Adaptee类,把Adaptee类的API与Target类的API衔接起来。

  涉及到的角色:

  目标(Target)角色:类适配器模式中目标不可以是类,只能是接口。

  源(Adapee)角色:具体类。

  适配器(Adaper)角色:具体类。

 public interface Target {
/**
* 这是源类Adaptee也有的方法
*/
public void sampleOperation1();
/**
* 这是源类Adapteee没有的方法
*/
public void sampleOperation2();
}
 public class Adaptee {

     public void sampleOperation1(){}

 }
 public class Adapter extends Adaptee implements Target {
/**
* 由于源类Adaptee没有方法sampleOperation2()
* 因此适配器补充上这个方法
*/
@Override
public void sampleOperation2() {
//写相关的代码
} }

  对象适配器模式

  对象的适配器模式把被适配的类的API转换成为目标类的API,使用委派关系连接到Adaptee类,见下图:

  

  Adapter与Adaptee是委派关系。

 public interface Target {
/**
* 这是源类Adaptee也有的方法
*/
public void sampleOperation1();
/**
* 这是源类Adapteee没有的方法
*/
public void sampleOperation2();
}
 public class Adaptee {

     public void sampleOperation1(){}

 }
 public class Adapter {
private Adaptee adaptee; public Adapter(Adaptee adaptee){
this.adaptee = adaptee;
}
/**
* 源类Adaptee有方法sampleOperation1
* 因此适配器类直接委派即可
*/
public void sampleOperation1(){
this.adaptee.sampleOperation1();
}
/**
* 源类Adaptee没有方法sampleOperation2
* 因此由适配器类需要补充此方法
*/
public void sampleOperation2(){
//写相关的代码
}
}

  类适配器和对象适配器比较:

  类适配器使用继承方式,不能访问Adaptee子类,可以重写父类方法;而对象适配器使用对象组合方式,可以访问Adaptee子类,不能重写父类方法。

  尽量使用对象适配器,少用继承。

  优点:更好的复用性和扩展性。

  缺点:过多的适配器会使系统变得混乱。

  缺省适配模式

  作为适配器模式的一个特例,缺省适配(Default Adapter)模式为一个接口提供缺省实现,子类型可以扩展这个缺省实现,不必扩展原有接口。

  鲁智深的故事

  和尚要做什么呢?吃斋、念经、打坐、撞钟、习武等。给出所有和尚都需要实现的方法对应的接口:

 public interface 和尚 {
public void 吃斋();
public void 念经();
public void 打坐();
public void 撞钟();
public void 习武();
public String getName();
}

  下面的鲁智深类通不过编译:

 public class 鲁智深 implements 和尚{
public void 习武(){
拳打镇关西;
大闹五台山;
大闹桃花村;
火烧瓦官寺;
倒拔垂杨柳;
}
public String getName(){
return "鲁智深";
}
}

  当初鲁达剃度,众僧说:“此人形容丑恶、相貌凶顽,不可剃度他",但是长老却说:”此人上应天星、心地刚直。虽然时下凶顽,命中驳杂,久后却得清净。证果非凡,汝等皆不及他。”“应”者,实现也;“天星”者,抽象类也。

 public abstract class 天星 implements 和尚 {
public void 吃斋(){}
public void 念经(){}
public void 打坐(){}
public void 撞钟(){}
public void 习武(){}
public String getName(){
return null;
}
}

  抽象的天星类是一个适配器类,实现了和尚接口所要求的所有方法。

  鲁智深类继承抽象类“天星”:

 public class 鲁智深 extends 天星{
public void 习武(){
拳打镇关西;
大闹五台山;
大闹桃花村;
火烧瓦官寺;
倒拔垂杨柳;
}
public String getName(){
return "鲁智深";
}
}

 

  适配器模式目的是与目标接口相容,缺省适配模式目的是提供接口的一般实现类。如果不准备实现一个接口的所有方法,可以使用缺省适配模式来创建一个抽象类,给出所有方法的一般实现,继承该抽象类的子类不必实现所有方法。

  参考资料

  《JAVA与模式》之适配器模式

Java 适配器模式的更多相关文章

  1. JAVA适配器模式(从现实生活角度理解代码原理)

    说道JAVA中的适配器模式,不得不引用该设计模式的固定表述"适配器模式(Adapter ):将一个类的接口转换成客户希望的另外一个接口,适配器模式使得原本由于接口不兼容而不能一起工作的那些类 ...

  2. java适配器模式随笔记

    今天学习了一下java中的适配器模式,在这里做个记录,方便以后查看 什么是适配器,适配就是连接源到目标的中间件,简单的例子就是我们的港水货手机充电器是大三角,我们想要在大陆正常使用我们需要一个转接充电 ...

  3. Java适配器模式的简单应用

    对于刚从工厂生产出来的商品,有些功能并不能完全满足用户的需要.因此,用户通常会对其进行一定的改装工作.编写程序为普通的汽车增加GPS定位功能,借此演示适配器模式的用法. 思路分析: 这个问题的需求是, ...

  4. java 适配器模式实现代码

    目录 1.适配器模式 1.1.类适配器 1.2.对象适配器 2.适配器模式实例 1.适配器模式 适配器模式可以分为类适配器和对象适配器. 1.1.类适配器 //目标接口 interface Targe ...

  5. [设计原则与模式] Java 适配器模式

    cp from : https://blog.csdn.net/xiaouncle/article/details/80553923 设计模式本质上就是“SOLID设计原则”在实际应用中的具体体现,我 ...

  6. java——适配器模式、策略模式

    适配器模式: https://www.cnblogs.com/honger/p/5970283.html 策略模式: https://www.jianshu.com/p/3bcf55cf83d3

  7. java适配器模式

    原文查看:http://www.cnblogs.com/java-my-life/archive/2012/04/13/2442795.html

  8. java 适配器模式(adapter pattern)

    适配器就是一种适配中间件,它存在于不匹配的二者之间,用于连接二者,将不匹配变得匹配. 场景:电脑读取内存卡中的内容,内存卡是没有办法直接插在电脑的USB接口上,那就不需要一个转换器. 下面的例子实现了 ...

  9. Java设计模式中适配器模式的实现方法

    在Java开发中,我们常常需要用到Java接口型模式中的适配器模式,那适配器设计模式到底是什么模式呢? 适配器模式(Adapter)就是把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹 ...

随机推荐

  1. NodeJs——router报错原因

    rout.js var http = require('http'); var url = require('url'); var router = require('./models/router. ...

  2. python with语句中的变量有作用域吗?

    一直以为python中的with语句中的变量,只在with语句块中起作用.不然为什么要缩进一个级别呢? 呵呵,然而并没有为with语句内的变量创建新的作用域. 举例: # test.py with o ...

  3. PAT Basic 1073. 多选题常见计分法

    题目内容 多选题常见计分法(20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 批改多选题是比较麻烦的事情,有 ...

  4. SNMP MIBs and IPv6

    https://www.cisco.com/c/en/us/about/security-center/snmp-mib-ipv6.html

  5. AndroidStudio在线搜索最新版本的依赖库

    操作步骤 打开File–>Project Structure 选中当前项目,点击Denpendencies标签 点击+,选Library dependency 打开界面如下: 输入想要的依赖库部 ...

  6. springboot1.5.4 集成cxf完整实例

    WebService 服务端 添加依赖 <?xml version="1.0" encoding="UTF-8"?> <project xml ...

  7. CGAffineTransform的使用

    typedef struct CGAffineTransform CGAffineTransform; struct CGAffineTransform { CGFloat a, b, c, d; C ...

  8. XNginx - nginx 集群可视化管理工具

    之前团队的nginx管理,都是运维同学每次去修改配置文件,然后重启,非常不方便,一直想找一个可以方便管理nginx集群的工具,翻遍web,未寻到可用之物,于是自己设计开发了一个. 效果预览 集群gro ...

  9. Codeforces 596D Wilbur and Trees dp (看题解)

    一直在考虑, 每一段的贡献, 没想到这个东西能直接dp..因为所有的h都是一样的. #include<bits/stdc++.h> #define LL long long #define ...

  10. 请使用千位分隔符(逗号)表示web网页中的大数字

    方法一:使用正则表达式 语法如下: String(Number).replace(/(\d)(?=(\d{3})+$)/g, "$1,"); 举例: String(12345678 ...