原文:http://www.runoob.com/design-pattern/
少许个人理解,如有错误请指出(本文基本照搬,因为比较简单)

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于
结构型模式 它结合了两个独立接口的功能。
这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。
我们通过下面的实例来演示适配器模式的使用。其中,音频播放器设备只能播放 mp3 文件,通过使用一个更高级的音频播放器来播放 vlc 和 mp4 文件。

意图:
将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

主要解决:
主要解决在软件系统中,常常要将一些”现存的对象”放到新的环境中,而新环境要求的接口是现对象不能满足的。

何时使用:
1、系统需要使用现有的类,而此类的接口不符合系统的需要。 (需要扩充)
2、想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作,这些源类不一定有一致的接口。
3、通过接口转换,将一个类插入另一个类系中。(比如老虎和飞禽,现在多了一个飞虎,在不增加实体的需求下,增加一个适配器,在里面包容一个虎对象,实现飞的接口。)

如何解决:
继承或依赖(推荐)。

关键代码:
适配器继承或依赖已有的对象,实现想要的目标接口。

类比现实:
1、美国电器 110V,中国 220V,就要有一个适配器将 110V 转化为 220V。
2、JAVA JDK 1.1 提供了 Enumeration 接口,而在 1.2 中提供了 Iterator 接口,想要使用 1.2 的 JDK,则要将以前系统的 Enumeration 接口转化为 Iterator 接口,这时就需要适配器模式。
3、在 LINUX 上运行 WINDOWS 程序。

优点:
1、可以让任何两个没有关联的类一起运行。
2、提高了类的复用。
3、增加了类的透明度。
4、灵活性好。

缺点:
1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
2.由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。

使用场景:
有动机地修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。

注意事项:
适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。

实例演示:
我们有一个 MediaPlayer 接口和一个实现了 MediaPlayer 接口的实体类 AudioPlayer。默认情况下,AudioPlayer 可以播放 mp3 格式的音频文件。
我们还有另一个接口 AdvancedMediaPlayer 和实现了 AdvancedMediaPlayer 接口的实体类。该类可以播放 vlc 和 mp4 格式的文件。
我们想要让 AudioPlayer 播放其他格式的音频文件。为了实现这个功能,我们需要创建一个实现了 MediaPlayer 接口的适配器类 MediaAdapter,并使用 AdvancedMediaPlayer 对象来播放所需的格式。
AudioPlayer 使用适配器类 MediaAdapter 传递所需的音频类型,不需要知道能播放所需格式音频的实际类。AdapterPatternDemo,我们的演示类使用 AudioPlayer 类来播放各种格式。

适配器模式的 UML 图

步骤 1
为媒体播放器和更高级的媒体播放器创建接口。
MediaPlayer.java

public interface MediaPlayer {public void play(String audioType, String fileName);
}
AdvancedMediaPlayer.java
public interface AdvancedMediaPlayer {  public void playVlc(String fileName);public void playMp4(String fileName);
}

步骤 2
创建实现了 AdvancedMediaPlayer 接口的实体类。
VlcPlayer.java

public class VlcPlayer implements AdvancedMediaPlayer{@Overridepublic void playVlc(String fileName) {System.out.println("Playing vlc file. Name: "+ fileName);     }@Overridepublic void playMp4(String fileName) {//什么也不做}
}

Mp4Player.java

public class Mp4Player implements AdvancedMediaPlayer{@Overridepublic void playVlc(String fileName) {//什么也不做}@Overridepublic void playMp4(String fileName) {System.out.println("Playing mp4 file. Name: "+ fileName);     }
}

步骤 3
创建实现了 MediaPlayer 接口的适配器类。
MediaAdapter.java

public class MediaAdapter implements MediaPlayer {AdvancedMediaPlayer advancedMusicPlayer;public MediaAdapter(String audioType){if(audioType.equalsIgnoreCase("vlc") ){advancedMusicPlayer = new VlcPlayer();         } else if (audioType.equalsIgnoreCase("mp4")){advancedMusicPlayer = new Mp4Player();} }@Overridepublic void play(String audioType, String fileName) {if(audioType.equalsIgnoreCase("vlc")){advancedMusicPlayer.playVlc(fileName);}else if(audioType.equalsIgnoreCase("mp4")){advancedMusicPlayer.playMp4(fileName);}}
}

步骤 4
创建实现了 MediaPlayer 接口的实体类。
AudioPlayer.java

public class AudioPlayer implements MediaPlayer {MediaAdapter mediaAdapter; @Overridepublic void play(String audioType, String fileName) {        //播放 mp3 音乐文件的内置支持if(audioType.equalsIgnoreCase("mp3")){System.out.println("Playing mp3 file. Name: "+ fileName);          } //mediaAdapter 提供了播放其他文件格式的支持else if(audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")){mediaAdapter = new MediaAdapter(audioType);mediaAdapter.play(audioType, fileName);}else{System.out.println("Invalid media. "+audioType + " format not supported");}}
}

步骤 5
使用 AudioPlayer 来播放不同类型的音频格式。
AdapterPatternDemo.java

public class AdapterPatternDemo {public static void main(String[] args) {AudioPlayer audioPlayer = new AudioPlayer();audioPlayer.play("mp3", "beyond the horizon.mp3");audioPlayer.play("mp4", "alone.mp4");audioPlayer.play("vlc", "far far away.vlc");audioPlayer.play("avi", "mind me.avi");}
}

步骤 6
验证输出。

Playing mp3 file. Name: beyond the horizon.mp3
Playing mp4 file. Name: alone.mp4
Playing vlc file. Name: far far away.vlc
Invalid media. avi format not supported

总结:还调用原来的接口(AudioPlayer),如果原来的接口无法解决问题或无法处理(无法播放对应格式的文件),则调用适配器,适配器糅合了其他格式播放器的功能,可以处理某些原接口无法处理的东西。

设计模式笔记六:适配器模式相关推荐

  1. 设计模式笔记(7)---适配器模式(结构型)

    Gof定义 将一个类的接口转换成客户所希望的另一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 动机 在软件系统中,由于应用环境的变化,常常要将"一些现存的对象 ...

  2. Java设计模式笔记——七个结构型模式

    系列文章目录 第一章 Java设计模式笔记--七大设计原则 第二章 Java设计模式笔记--六个创建型模式 文章目录 系列文章目录 一.适配器模式 1.概念 2.类适配器 3.对象适配 4.缺省适配器 ...

  3. 结构型模式的设计模式笔记

    此笔记是在软件秘笈-设计模式那点事上做的笔记 一.适配器模式 1.设计思路 既有的软件结构具有稳定运行的基础,但是却无法直接利用到新的程序当中,这时就需要一个适配器,在原有内容和新的结果之间沟通,从而 ...

  4. Head First设计模式笔记

    Head First设计模式第一课:策略模式 刚刚看<Head First 设计模式>,第一章讲了一个故事: 设计师Joe设计了只鸭子,但董事会(难道不是执行经理管这事)要求每六个月改变产 ...

  5. android常用两种适配器,Android常见设计模式五:适配器模式

    对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次.而在android开发中,必要的了解一些设计模式又是必须的,因为设计模式在Android源码 ...

  6. 重学 Java 设计模式:实战适配器模式

    重学 Java 设计模式:实战适配器模式 一.前言 擦屁屁纸80%的面积都是保护手的! 工作到3年左右很大一部分程序员都想提升自己的技术栈,开始尝试去阅读一些源码,例如Spring.Mybaits.D ...

  7. 肝一肝设计模式【六】-- 装饰器模式

    系列文章目录 肝一肝设计模式[一]-- 单例模式 传送门 肝一肝设计模式[二]-- 工厂模式 传送门 肝一肝设计模式[三]-- 原型模式 传送门 肝一肝设计模式[四]-- 建造者模式 传送门 肝一肝设 ...

  8. Ethernet/IP 学习笔记六

    Ethernet/IP 学习笔记六 EtherNet/IP defines two primary types of communications: explicit and implicit (Ta ...

  9. 吴恩达《机器学习》学习笔记六——过拟合与正则化

    吴恩达<机器学习>学习笔记六--过拟合与正则化 一. 过拟合问题 1.线性回归过拟合问题 2.逻辑回归过拟合问题 3.过拟合的解决 二. 正则化后的代价函数 1.正则化思想 2.实际使用的 ...

最新文章

  1. 20162328蔡文琛week07
  2. I.MX6开发板移植Linux4.1.15内核之TSC2007触摸屏设备树信息的添加
  3. SpringBoot项目部署到独立的Tomcat上
  4. ASP.NET MVC 4 小项目开发总结
  5. 大数据平台不是救世主!做好数字化转型,得先解决这一问题
  6. Keras:Transfer learning
  7. 第二篇:稳定性之如何有条不紊地应对风险?
  8. Python_微信开发
  9. 什么是python构造方法_什么是Python?
  10. silverlight html 传参,Silverlight与html、JavaScript三者交互
  11. [Bochs]Bochs调试技术
  12. html5 下拉树,HTML5拖拽API实现vue树形拖拽组件
  13. 就计算机应用领域而言航天器,婴幼儿耳道长耵聍,应该用()工具取出A.耳挖勺B.火柴棍C.棉签D.卡子...
  14. Linux内核设计与实现 Robert Love
  15. Xmanager学习1_Xbrowser无法连接到Linux的解决办法
  16. 微信刷脸支付php后端,2.1 微信刷脸支付初始化
  17. LeNet-5网络结构详解
  18. 教你用Canvas将图片截成圆图
  19. 获取拉勾网招聘信息数据
  20. Cobalt Strike的安装

热门文章

  1. django,cbv,模板层
  2. Java JPA学习与使用小记
  3. PAT-乙级-1034 有理数四则运算
  4. H5的本地保存localStorage、sessionStorage用法总结
  5. cloudera cdh5.13.0 vmware 快速安装
  6. Android商城开发系列(一)——开篇
  7. 关于ie7下display:inline-block;不支持的解决方案
  8. Unity3D 5.x 简单实例 - 发射炮弹
  9. 8个很棒的 jQuery 倒计时插件和教程
  10. 2005.2.21 至 2005.8.8