Java 适配器模式
在阎宏博士的《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适配器模式(从现实生活角度理解代码原理)
		说道JAVA中的适配器模式,不得不引用该设计模式的固定表述"适配器模式(Adapter ):将一个类的接口转换成客户希望的另外一个接口,适配器模式使得原本由于接口不兼容而不能一起工作的那些类 ... 
- java适配器模式随笔记
		今天学习了一下java中的适配器模式,在这里做个记录,方便以后查看 什么是适配器,适配就是连接源到目标的中间件,简单的例子就是我们的港水货手机充电器是大三角,我们想要在大陆正常使用我们需要一个转接充电 ... 
- Java适配器模式的简单应用
		对于刚从工厂生产出来的商品,有些功能并不能完全满足用户的需要.因此,用户通常会对其进行一定的改装工作.编写程序为普通的汽车增加GPS定位功能,借此演示适配器模式的用法. 思路分析: 这个问题的需求是, ... 
- java 适配器模式实现代码
		目录 1.适配器模式 1.1.类适配器 1.2.对象适配器 2.适配器模式实例 1.适配器模式 适配器模式可以分为类适配器和对象适配器. 1.1.类适配器 //目标接口 interface Targe ... 
- [设计原则与模式]   Java 适配器模式
		cp from : https://blog.csdn.net/xiaouncle/article/details/80553923 设计模式本质上就是“SOLID设计原则”在实际应用中的具体体现,我 ... 
- java——适配器模式、策略模式
		适配器模式: https://www.cnblogs.com/honger/p/5970283.html 策略模式: https://www.jianshu.com/p/3bcf55cf83d3 
- java适配器模式
		原文查看:http://www.cnblogs.com/java-my-life/archive/2012/04/13/2442795.html 
- java 适配器模式(adapter pattern)
		适配器就是一种适配中间件,它存在于不匹配的二者之间,用于连接二者,将不匹配变得匹配. 场景:电脑读取内存卡中的内容,内存卡是没有办法直接插在电脑的USB接口上,那就不需要一个转换器. 下面的例子实现了 ... 
- Java设计模式中适配器模式的实现方法
		在Java开发中,我们常常需要用到Java接口型模式中的适配器模式,那适配器设计模式到底是什么模式呢? 适配器模式(Adapter)就是把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹 ... 
随机推荐
- WPF应用程序内存泄漏的一些原因
			原文:Finding Memory Leaks in WPF-based applications There are numbers of blogs that folks wrote about ... 
- Redis的搭建和Redis的集群搭建
			1.Redis的官网:https://redis.io/ Redis的测试网站:http://try.redis.io/ 2.参考博客:https://www.cnblogs.com/maf ... 
- 山寨版 WP8.1 Cortana 启动 PC
			8.1 dev preview 发布以来 Cortana 很受关注 前一段看到有视频演示用 Cortana 来启动 PC 看视频也是启动第三方应用实现的,简单来弄其实就是个语音启动应用 + 网络唤醒么 ... 
- Not running in a hosted service or the Development Fabric
			今天尝试在azure上发布网站后,无法正常访问 本地调试也提示: Not running in a hosted service or the Development Fabric 谷歌百度半天… 最 ... 
- js 函数参数为什么是按值传递?
			首先说下,在js中有两大类数据类型: 基本类型和引用类型. 其次,基本类型有5种: Undefined,Null,Boolean,Number.String, 引用类型有一种: Object(Func ... 
- 【bzoj3589】动态树 树链剖分+树链的并
			题解: 树链剖分是显然的 问题在于求树链的并 比较简单的方法是 用线段树打标记覆盖,查询标记区间大小 Qlog^2n 代码: #include <bits/stdc++.h> using ... 
- MySQL主从数据同步延时分析
			一.MySQL数据库主从同步延迟 要了解MySQL数据库主从同步延迟原理,我们 ... 
- LVM分区无损增减
			http://www.361way.com/change-lvm-size/1792.html 
- HTML5拖放牛刀小试
			<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ... 
- JAXB在Java 9/10并且使用Tomcat 9的问题
			Implementation of JAXB-API has not been found on module path or classpath. JAXB API是java EE 的API,jav ... 
