正文

一、定义

适配器模式将一个类的接口(被适配者),转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。

要点:

  • 适配器实现了目标接口,并持有被适配者的实例。
  • 适配器使用被适配者的方法,把请求转换成被适配者的一个或多个方法。
  • 客户通过目标接口调用适配器的方法对适配器发出请求。
  • 客户与被适配者是解耦的,一个不知道另一个。
  • 当需要使用一个现有的类而其接口并不符合你的需要时,就使用适配器。

二、实现步骤

1、创建被适配者接口

/**
* 被适配者接口
*/
public interface Adaptee { public void specificRequest();
}

2、创建具体的被适配者,并实现被适配者接口

/**
* 具体的被适配者
*/
public class ConcreteAdaptee implements Adaptee { @Override
public void specificRequest() {
System.out.println("ConcreteAdaptee is doing something...");
}
}

3、创建目标接口

/**
* 目标接口
*/
public interface Target { public void request();
}

4、创建适配器类,并实现目标接口

适配器持有被适配者,并在收到请求时调用被适配者的方法。

/**
* 适配器
*/
public class Adapter implements Target { /**
* 被适配者
*/
Adaptee adaptee; public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
} @Override
public void request() {
// 调用被适配者方法
adaptee.specificRequest();
}
}

5、使用适配器转换被适配者

public class Test {

    public static void main(String[] args) {
// 被适配者
Adaptee adaptee = new ConcreteAdaptee();
// 适配器
Adapter adapter = new Adapter(adaptee);
adapter.request();
}
}

三、举个栗子

1、背景

你上班的公司做了一套模拟鸭子游戏。现在,假设你缺鸭子对象,想用一些火鸡对象来冒充。

显而易见,因为火鸡的接口不同,所以我们不能公然拿来用。

2、实现

使用适配器把火鸡的方法转换成鸭子的方法,这样表面上看起来就像是一只鸭子了。

(1)创建火鸡接口

/**
* 火鸡接口(被适配者)
*/
public interface Turkey { /**
* 咯咯叫
*/
public void gobble(); /**
* 飞行
*/
public void fly();
}

(2)创建具体的火鸡

/**
* 野火鸡
*/
public class WildTurkey implements Turkey { @Override
public void gobble() {
System.out.println("Gobble gobble");
} @Override
public void fly() {
System.out.println("I'm flying a short distance");
}
}

(3)创建鸭子接口

/**
* 鸭子接口(目标接口)
*/
public interface Duck { /**
* 呱呱叫
*/
public void quark(); /**
* 飞行
*/
public void fly();
}

(4)创建火鸡适配器,并实现鸭子接口

/**
* 火鸡适配器
*/
public class TurkeyAdapter implements Duck { /**
* 火鸡
*/
Turkey turkey; public TurkeyAdapter(Turkey turkey) {
this.turkey = turkey;
} @Override
public void quark() {
turkey.gobble();
} @Override
public void fly() {
// 火鸡飞行距离比鸭子短,因此需要调用5次火鸡的fly()方法。
for (int i = 0; i < 5; i++) {
turkey.fly();
}
}
}

(5)使用火鸡适配器,将火鸡适配成鸭子

public class Test {

    public static void main(String[] args) {
// 火鸡(被适配者)
Turkey turkey = new WildTurkey();
// 火鸡适配器
TurkeyAdapter turkeyAdapter = new TurkeyAdapter(turkey);
turkeyAdapter.quark();
turkeyAdapter.fly();
}
}

《Head First 设计模式》:适配器模式的更多相关文章

  1. 20. 星际争霸之php设计模式--适配器模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  2. Java设计模式——适配器模式

    JAVA 设计模式 适配器模式 用途 适配器模式 (Adapter) 将一个类的接口转换成客户希望的另外一个接口. Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 适配器 ...

  3. linkin大话设计模式--适配器模式

    linkin大话设计模式--适配器模式 大家知道,在java中只允许单继承,但是在实际问题中往往都需要多继承,java引入了接口这一概念.(一个类可以实现多个接口) 由于接口中都是抽象方法,那么我们在 ...

  4. php设计模式适配器模式

    php设计模式适配器模式 简介 适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的.一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起. 其实就是通过一个转换类,这个转 ...

  5. 【设计模式】Java设计模式 - 适配器模式

    [设计模式]Java设计模式 - 适配器模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一 ...

  6. [Head First设计模式]身边的设计模式——适配器模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  7. JAVA 设计模式 适配器模式

    用途 适配器模式 (Adapter) 将一个类的接口转换成客户希望的另外一个接口. Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 适配器模式是一种结构型模式. 结构

  8. Java设计模式 - 适配器模式

    概念: 将一个类的接口,转换成客户期望的另一个接口.适配器模式让原来接口不兼容的类可以在一起工作. 解决的问题: 提供类似于中间人的作用:把原本不兼容.不能一起工作的接口组合在一起,使得它们能够在一起 ...

  9. 24种设计模式--适配器模式【Adapter Pattern】

    今天讲适配器模式,这个模式也很简单,你笔记本上的那个拖在外面的黑盒子就是个适配器,一般你在中国能用,在日本也能用,虽然两个国家的的电源电压不同,中国是 220V,日本是 110V,但是这个适配器能够把 ...

  10. 结合JDK源码看设计模式——适配器模式

    定义: 将一个类的接口转换成客户期望的另外一个接口(重点理解适配的这两个字),使得接口不兼容的类可以一起工作适用场景: 已经存在的类,它的方法和需求不匹配的时候 在软件维护阶段考虑的设计模式 详解 首 ...

随机推荐

  1. 关于C# winform唤起本地已安装应用程序(测试win10,win7可用)

    想要唤起本地已安装应用程序,我想到的有三种可行的方法: 第一种就是打开本地的快捷方式(有的应用可能没有快捷方式,但这种方法效率最高,可配合其他方法使用),快捷方式分为本地桌面快捷方式和开始菜单中的快捷 ...

  2. Problem C: 计算机类

    Description 定义一个Computer类,有两个属性: 1. 字符串属性name,用于表示计算机的名字. 2. 静态整型属性cnt,用于记录产生的计算机对象的个数. 至少有如下成员函数: 1 ...

  3. 阿里云OSS服务器的使用

    关于文件上传,我们一般使用OSS服务器.大致为两种上传方式: 详情官网参考:https://help.aliyun.com/document_detail/31927.html?spm=a2c4g.1 ...

  4. flask中的endpoint是什么

    app.view_functions 是一个字典,里面是存储的是 endpoint 与 视图函数的键值对,如果没指名函数视图的endpoint,默认是函数名,而 url_map 是一个列表,里面是ur ...

  5. onsubmit校验表单时利用ajax的return false无效解决方法-转

    原来的代码 function checkNewEmail(){ var re_email=new RegExp("\\w+@\\w+\\.\\w+\\.?\\w*");      ...

  6. 中缀转逆波兰表达式 c++ 队列,栈

    记得早在几十天以前,xty 学长曾让我学这个.一直推到了现在哈 咕咕咕(能鸽善鹉orz) 抱歉,学妹我来还愿了! 中缀表达式比较适合人类的计算,但是后缀表达式更适合机器计算(毕竟没有那么多运算符优先级 ...

  7. ubuntu的docker安装

    安装docker 安装 介绍一下docker 的中央仓库们 Docker官方中央仓库: https://hub.docker.com/ 因为docker 网站在国外所以访问速度和你的运气有关还有网络. ...

  8. 巩固复习(Django最基础的部分_具体查看官方文档)

    Django学习路1 1.脚本不能随便运行,没准 linux 运行完就上不去了 2.pip 在 linux 上 写 pip3 同理 python 写为 python3 3.在 pycharm 上安装库 ...

  9. Skill 脚本演示 ycMPPTap.skl

    https://www.cnblogs.com/yeungchie/ ycMPPTap.skl 主要用于创建自定的 Tap 类型(指定 掺杂类型 / Via 数量 / Active 宽度),并可以通过 ...

  10. Virtuoso 中的窗口_1

    https://www.cnblogs.com/yeungchie/ hiDisplayAppDBox(简单弹出一个字符串,Tips) prog((TipsForm) hiDisplayAppDBox ...