定义:

将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
 
书中说到Gof的设计模式中,讲了两种类型的适配器模式:
1.类适配器模式
2.对象适配器模式
其中,类适配器模式,是通过多重继承来实现了。
但是Java是不支持多重继承的,所以下面主要讲的是对象适配器模式。
 

结构:(书中图,侵删)

一个客户真正要使用的目标接口(具体一点说可以叫方法),包含它的可以是接口、抽象类、类
一个需要被适配的接口(方法),同上
一个适配器,继承自目标接口,包含一个需要被适配的接口
 

实例:

书中提到一个电源适配器的例子,很形象,所以这里提一嘴。
就是中国的电源是220V,但有的国家是110V,出国之后依旧想使用中国的电器怎么办?就需要用到适配器来转换一下电压。
说到这里,我就想到了一个例子,护照。
中国公民有中国的身份证,外国人也有外国的id card,我们不能指望外国人都用中国的身份证,同样我们也不可能都使用外国的id card。
但是出入境怎么验证你的身份呢,这就需要用到护照,护照就相当于全球通用的身份证。我们这里忽略签证的存在,签证也要盖在护照上不是。
 
目标类(外国身份认证):
package designpattern.adapter;

import java.util.HashSet;
import java.util.Set; public class ForeignIdentify {
String socailSecurityNumber; // 模拟一个社保号的数据库
static Set<String> dbSet = new HashSet<>();
static {
dbSet.add("F001");
dbSet.add("F002");
dbSet.add("F003");
} public boolean check(String socailSecurityNumber) {
if (dbSet.contains(socailSecurityNumber)) {
System.out.println(socailSecurityNumber + "是外国的合法公民");
return true;
} else {
System.out.println(socailSecurityNumber + "不是外国的合法公民");
return false;
} }
}
被适配类(中国身份认证):
package designpattern.adapter;

import java.util.HashSet;
import java.util.Set; public class ChineseIdentify {
String idCardNumber; // 模拟一个身份证号的数据库
static Set<String> dbSet = new HashSet<>();
static {
dbSet.add("张三C001");
dbSet.add("李四C002");
dbSet.add("王五C003");
} public boolean check(String idCardNumber, String name) {
if (dbSet.contains(name + idCardNumber)) {
System.out.println(name + idCardNumber + "是中国的合法公民");
return true;
} else {
System.out.println(name + idCardNumber + "不是中国的合法公民");
return false;
} }
}
适配器(护照):
package designpattern.adapter;

import java.util.HashMap;
import java.util.Map; public class ChinesePassport extends ForeignIdentify {
ChineseIdentify chineseIdentify = new ChineseIdentify(); // 模拟身份证、名字对应数据库
static Map<String, String> db = new HashMap<>();
static {
db.put("C001", "张三");
db.put("C002", "李四");
db.put("C003", "王五"); } @Override
public boolean check(String idCardNumber) {
// 为了模拟两个接口不完全一样,假设中国的身份验证需要身份证号和名字两个条件
return chineseIdentify.check(idCardNumber, getName(idCardNumber));
} private String getName(String idCardNumber) {
return db.get(idCardNumber);
}
}
客户端:
package designpattern.adapter;

public class Client {
public static void main(String[] args) { ForeignIdentify foreignIdentify = new ForeignIdentify();
enter("F001", foreignIdentify);
enter("F004", foreignIdentify); // 直接用身份证号来验证
enter("C003", foreignIdentify);
// 换成护照
foreignIdentify = new ChinesePassport();
enter("C003", foreignIdentify);
} public static void enter(String number, ForeignIdentify foreignIdentify) {
System.out.println("=============外国入关==============");
if (foreignIdentify.check(number)) {
System.out.println("允许入关!");
} else {
System.out.println("禁止入关!");
} }
}

结果输出:

=============外国入关==============
F001是外国的合法公民
允许入关!
=============外国入关==============
F004不是外国的合法公民
禁止入关!
=============外国入关==============
C003不是外国的合法公民
禁止入关!
=============外国入关==============
王五C003是中国的合法公民
允许入关!

总结:

这个模式准确的说是一个无奈的选择,不应该当做第一选择,当需要适配的两样东西不好改动的时候,为了让他们能匹配上,才不得不使用适配器。
如果能够提前避免接口不匹配的情况,及时进行代码的重构是更好的选择。就像如果说有电子设备都是同样的充电口,那我们就不需要准备他们多条充电线了。

设计模式 | 适配器模式(adapter)的更多相关文章

  1. 设计模式 - 适配器模式(adapter pattern) 具体解释

    适配器模式(adapter pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 适配器模式(adapter pattern): 将一个类的接 ...

  2. 设计模式 - 适配器模式(adapter pattern) 枚举器和迭代器 具体解释

    适配器模式(adapter pattern) 枚举器和迭代器 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考适配器模式(adapter patter ...

  3. 设计模式--适配器模式Adapter(结构型)

    一.适配器模式 适配器模式的主要作用是在新接口和老接口之间进行适配.将一个类的接口转换成客户端期望的另外一个接口.其实适配器模式有点无赖之举,在前期设计的时候,我们就不应该考虑适配器模式,而应该通过重 ...

  4. 说说设计模式~适配器模式(Adapter)

    返回目录 之前和大家一起谈了工厂模式和单例模式,今天来看一下另一种非常常用的模式,它就是适配器模式,第一次看到这个模式是通过“张逸”老师的“设计之道”这篇文章,在这里表adapter讲的很透彻,今天把 ...

  5. [工作中的设计模式]适配器模式adapter

    一.模式解析 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 也就是说,如果已经写好了一个接口,但是又来了一种截然不同的接口,如 ...

  6. C#设计模式——适配器模式(Adapter Pattern)

    一.概述在软件开发中,常常会想要复用一个已经存在的组件,但该组件的接口却与我们的需要不相符,这时我们可以创建一个适配器,在需复用的组件的接口和我们需要的接口间进行转换,从而能够正常的使用需复用的组件. ...

  7. 设计模式-适配器模式(Adapter)

    简介: 适配器模式在我看来是最无聊的一种模式,因为他根本不是一种新的创意模式,而是一种不得已而为之的模式.就算不学适配器模式,在具体应用场景中也会自然而然的想到这种解决方案. 张三在英国留学时买了个笔 ...

  8. 大话设计模式--适配器模式 Adapter -- C++实现实例

    1.适配器模式: 将一个类的接口转换为客户希望的另一个接口,使得原来由于接口不能一起工作的那些类一起工作. 适配器模式一般用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况. 适配器模式分 ...

  9. [设计模式]适配器模式Adapter

    将一个类的接口转换成客户希望的另外一个接口. A d a p t e r模式使得原本 由于接口不兼容而不能一起工作的那些类可以一起工作.

  10. 设计模式(五)适配器模式Adapter(结构型)

      设计模式(五)适配器模式Adapter(结构型) 1. 概述: 接口的改变,是一个需要程序员们必须(虽然很不情愿)接受和处理的普遍问题.程序提供者们修改他们的代码;系统库被修正;各种程序语言以及相 ...

随机推荐

  1. 【汇总】java中数组的声明、初始化及遍历

    java中数组用来存储固定大小的同类型元素 一维数组: 1.数组的声明: //声明一维数组,推荐用第一种 int[] a; int b[]; 2.数据的初始化:有三种初始化方式 (1).静态初始化 / ...

  2. Python使用Flask框架,结合Highchart,搭配数据功能模块处理csv数据

    参考链接:https://www.highcharts.com.cn/docs/data-modules 1.javascript代码 var csv = document.getElementByI ...

  3. python面向对象的特点,类定义等,私有属性、公有属性、成员属性

    引子:类的对象在内存中的表示def dog(name,dog_type): def bark(d): print(d,'wang wang wang ...') data = { 'name':nam ...

  4. 窥探原理:实现一个简单的前端代码打包器 Roid

    roid roid 是一个极其简单的打包软件,使用 node.js 开发而成,看完本文,你可以实现一个非常简单的,但是又有实际用途的前端代码打包工具. 如果不想看教程,直接看代码的(全部注释):点击地 ...

  5. Python基础之变量进阶

    变量的引用 变量和数据都是保存在内存中的: 在python中函数的参数传递以及返回值都是靠引用传递的. 函数引用的概念 在python中 变量和数据时分开存储的: 数据保存在内存中的一个位置: 变量保 ...

  6. 2.8 补充:shell变量引用方式

    一 变量   变量:本质上是程序中保存用户数据的一块内存空间,变量名就是内存空间地址.   Shell中:变量可由字母数字和下划线组成,以字母或下划线开头.   命名:PATH=/sbin       ...

  7. DS26C31M和DS26C32AM

    DS26C31M是产生差分信号的芯片,实际使用的时候,测得在5V供电的情况下,输出+和输出-的压差是5V其中输出+和输入的特性相同. DS26C32AM是接收差分信号的芯片,与DS26C31M可以向配 ...

  8. 【Codeforces 598D】Igor In the Museum

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 同一个联通块里面答案都一样. 把每个联通块的答案都算出来 然后赋值就好 [代码] #include <bits/stdc++.h> ...

  9. 【Codeforces 486C】Palindrome Transformation

    [链接] 我是链接,点我呀:) [题意] 光标一开始在p的位置 你可以用上下左右四个键位移动光标(左右)或者更改光标所在的字符(上下增加或减少ascill码) 问你最少要操作多少次才能使得字符串变成回 ...

  10. [HDU3586]Information Disturbing(DP + 二分)

    传送门 题意:给定一个带权无向树,要切断所有叶子节点和1号节点(总根)的联系,每次切断边的费用不能超过上限limit,问在保证总费用<=m下的最小的limit 二分答案,再 DP,看看最终结果是 ...