适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。

这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。

概述


  • 意图

    将一个类的接口转换成客户希望的另外一个接口。

    适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

  • 主要解决

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

  • 何时使用

  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 程序。
  4. JAVA 中的 jdbc。
  • 优点
  1. 可以让任何两个没有关联的类一起运行。
  2. 提高了类的复用。
  3. 增加了类的透明度。
  4. 灵活性好。
  • 缺点
  1. 过多地使用适配器,会让系统非常零乱,不易整体进行把握。

    比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
  2. 由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。
  • 使用场景

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

  • 注意事项

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

实现


  • 适配器模式有如下三个角色

    Target:目标抽象类

    Adapter:适配器类

    Adaptee:适配者类

  • step 1

    需要一个Adaptee接口:Robot.java。提供cry()run()方法。
 public interface Robot {
void cry(); void move();
}
  • step 2

    实现Adaptee接口:BioRobot.java。它可以叫和慢慢跑
 public class BioRobot implements Robot{

     public void cry() {
System.out.println("仿生机器人叫.....");
} public void move() {
System.out.println("仿生机器人慢慢移动....");
} }
  • step 3

    需要Target类:Dog.java。它可以汪和快跑
 public class Dog {
public void wang(){
System.out.println("小狗叫:汪汪.....");
} public void run(){
System.out.println("小狗快快跑......");
}
}
  • step 4

    轮到重点啦:适配器Adapter,这个适配器能够使仿生机器人像狗一样叫,一样跑。
 public class DogAdapter implements Robot{
Dog dog;
public DogAdapter(Dog dog){ //取得要适配的对象的引用
this.dog = dog;
} /**
* 实现接口中的方法,只需要在相应的方法间进行转换即可完成。
*/
public void cry() {
System.out.println("机器人模拟狗叫...");
dog.wang();
} public void move() {
System.out.println("机器人模拟狗跑...");
dog.run();
} public static void main(String[] args) {
BioRobot robot = new BioRobot(); //首先我们需要一个机器人
Dog dog = new Dog(); //和一只狗 //将这只狗包装到机器人中,使其有点儿像机器人
Robot dogRobot = new DogAdapter(dog); //然后是机器人叫和跑
System.out.println("BioRob cry.....");
dogRobot.cry();
dogRobot.move();
}
}

运行结果:

BioRob cry......
机器人模拟狗叫...
小狗叫:汪汪......
机器人模拟狗跑...
小狗快快跑......

设计模式学习心得<适配器 Adapter>的更多相关文章

  1. 设计模式学习心得<代理模式 Proxy>

    在代理模式(Proxy Pattern)中,一个类代表另一个类的功能.这种类型的设计模式属于结构型模式. 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口. 概述 意图 为其他对象提供 ...

  2. 设计模式系列之代理模式(Proxy Pattern)——对象的间接访问

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  3. 设计模式学习之代理模式(Proxy,结构型模式)(11)

    参考地址:http://www.cnblogs.com/zhili/p/ProxyPattern.html 一.引言 在软件开发过程中,有些对象有时候会由于网络或其他的障碍,以至于不能够或者不能直接访 ...

  4. 设计模式学习之代理模式(Proxy)

    一.代理模式的初衷 不想让客户端直接访问具体实现接口,客户端不应该直接访问具体实现,一般会涉及到以下四个对象 业务接口:定义客户端访问的接口,是实现类和代理类都需要实现的 实现类:实现了业务接口,真正 ...

  5. Java设计模式学习记录-代理模式

    代理模式 代理模式是常见设计模式的一种,代理模式的定义是:为其他对象提供一种代理以控制对这个对象的访问. 在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起 ...

  6. 设计模式入门之代理模式Proxy

    //代理模式定义:为其它对象提供一种代理以控制对这个对象的訪问 //实例:鉴于书中给出的样例不太好.并且有些疑问,所以直接用保护代理作为实例 //要求,一旦订单被创建,仅仅有订单的创建人才干够改动订单 ...

  7. 学习笔记——代理模式Proxy

    代理模式,主要是逻辑和实现解耦.具体逻辑如何,由代理Proxy自己来设计,我们只需要把逻辑Subject交给代理即可. 主要应用场景,包括创建大开销对象时,使用代理来慢慢创建:远程代理,如网络不确定时 ...

  8. 《JAVA设计模式》之代理模式(Proxy)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述代理(Proxy)模式的: 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 代理模式的结 ...

  9. javascript设计模式学习之六——代理模式

    一.代理模式定义 代理模式的关键是:当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问.代理模式需要和本体对外提供相同的接口,对用户来说是透明的.代理模式的种类有 ...

  10. 设计模式学习心得<组合模式 Composite>

    组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式, ...

随机推荐

  1. Android 开发 PopupWindow弹窗

    简介 PopupWindow,顾名思义弹窗.PopupWindow是与AlertDialog在形式上类似的弹窗功能,都是为了在activity最上层显示一个弹窗.但是区别是PopupWindow可以自 ...

  2. 链表实现python list数据类型

    #1.<--用单链表的数据结构实现列表class error(Exception): def __init__(self,msg): super(error,self).__init__(sel ...

  3. 查看log日志

    本地环境的的log日志 可以直接查看, 对于新手来说怎么查看正式环境下的log日志呢 1, SSH到服务器 2,cd 到logs所在目录 3, tail -f 对应日志名字

  4. 一个linux 驱动升级的小问题记录

    重复踩了两次坑,所以简单记录下. 内核 3.10. 在修改了驱动的gro实现之后,进行驱动版本的升级,make && make install 之后,发现tg3的驱动,没有生效. 相同 ...

  5. flex布局-css

    1.html <div id="parent"> <div id="child1"></div>  <div id=& ...

  6. task 异步 进程与线程的区别

    用Wait方法(会以同步的方式来执行),不用Wait则会以异步的方式来执行 要在主线程中等待后台线程执行完毕,可以使用Wait方法(会以同步的方式来执行).不用Wait则会以异步的方式来执行. Tas ...

  7. ES6-你不知道的箭头函数

    一谈到ES6的箭头函数,大家可能想到的优点就是语法更简洁,因为去掉了return.function.{}等输入. 但是设计者果真就是出于简洁的目的推出的箭头函数吗?显然不是.   => 箭头函数 ...

  8. 1_translation_1

    It is always difficult to start describing a programming language because little details do not make ...

  9. Java & C# BCD编码与十进制转换

    using System;using System.Collections.Generic;using System.Text; namespace Base{ public class BCDHel ...

  10. python入门(十):模块、包

    模块:py文件包:目录,目录里面包含__init__.py,内容可以是空里面可以包含多个模块文件,还可以包含子包 1.模块和包,可以很方便的提供给其他程序以复用 1) 利于组织复杂工程 我们写代码的时 ...