适配器模式(Adapter)---结构型
1 基础知识
定义:将一个类的接口(被适配者)转换成客户期望的另一个接口(目标)。特征:使原本接口不兼容的类可以一起工作。
本质:转换匹配,复用功能。把不兼容的接口转换为客户端期望的样子从而实现功能的复用。
使用场景:已经存在的类,它的方法(接口)和需求不匹配时的解决方案。注意适配器模式不是软件设计阶段需要考虑的设计模式,而是随着软件维护,由于不同产品不同厂家造成功能类似而接口不相同情况下的解决方案。
优点:
更好的复用:性如果功能是已经有了的,只是接口不兼容,那么通过适配器模式就可以让这些功能得到更好的复用。
更好的可扩展性:在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。
2 代码示例
适配器的两种实现方式:
类适配器:
被适配者类:Adaptee
public class Adaptee {
public void adapteeRequest(){
System.out.println("被适配者的方法");
}
}
目标接口:Target
public interface Target {
void request();
}
目标实现:
public class ConcreteTarget implements Target {
@Override
public void request() {
System.out.println("concreteTarget目标方法");
}
}
适配者类:Adapter 通过继承和实现将被适配者类和目标联系在了一起
public class Adapter extends Adaptee implements Target{
@Override
public void request() {
//在此方法体内可以添加需要的代码
super.adapteeRequest();
}
}
应用层:
public class Test {
public static void main(String[] args) {
Target target = new ConcreteTarget();
//目标方法输出
target.request();
Target adapterTarget = new Adapter();
//适配者方法输出
adapterTarget.request();
}
}
其类图关系如下:

对象适配器:
修改适配者类:
public class Adapter implements Target{
//通过组合方式而不是继承
private Adaptee adaptee = new Adaptee();
@Override
public void request() {
//添加自己需要代码
adaptee.adapteeRequest();
}
}
应用层代码不变直接测试即可,其类关系图如下图,在代码中有一个原则如果继承和组合都可以满足要求优先选择组合。

场景使用:生活中的手机充电,需要把220V转换为5V电源。
220V电源:被适配者
public class AC220 {
public int outputAC220V(){
int output = 220;
System.out.println("输出交流电"+output+"V");
return output;
}
}
目标接口:5V电源
public interface DC5 {
int outputDC5V();
}
适配者:
public class PowerAdapter implements DC5{
private AC220 ac220 = new AC220();
@Override
public int outputDC5V() {
int adapterInput = ac220.outputAC220V();
//变压器...
int adapterOutput = adapterInput/44;
System.out.println("使用PowerAdapter输入AC:"+adapterInput+"V"+"输出DC:"+adapterOutput+"V");
return adapterOutput;
}
}
应用层:
public class Test {
public static void main(String[] args) {
DC5 dc5 = new PowerAdapter();
dc5.outputDC5V();
}
}
在实际开发中场景:如一个日志记录系统最初的的版本1:LogMode1 只有两个简单的功能以文件的形式读日志和写日志。
public interface LogMode1 {
public void writeLogFile();
public void readLogFile();
}
随着使用升级系统便有了版本2:将日志保存到数据库中可以对其进行增删改查
public interface LogMode12 {
//新增日志
public void creatLogFile();
//修改日志
public void updateLogFile();
//删除日志
public void removeLogFile();
//获取所有日志
public List<LogFile> getLogFile();
}
此时客户端提出需求,能否让版本2同时支持数据库存储和文件存储?直接的思路是进行合并但是有问题,现在客户端操作的第二版的日志接口,但第一版的接口与第二版的不同,客户端无法以同样的方式使用第一版的实现,如下图所示:

简单粗暴的方法是在第二版中增加文件存储功能,但是这些功能在第一版中已经实现过了,因此要避免重复劳动。解决方法就是采用适配器模式:Target接口相当于第二版的日志接口,被适配者则是第一版接口,采用类似前面提供的代码即可解决。
3 源代码中的使用
4 相关设计模式
(1)适配器模式与桥接模式
其实这两个模式除了结构略为相似外,功能上完全不同。适配器模式是把两个或者多个接口的功能进行转换匹配;而桥接模式是让接口和实现部分相分离,以便它们可以相对独立地变化。
(2)适配器模式与装饰模式
(3)适配器模式和代模式
适配器模式可以和代理模式组合使用。在实现近配器的时候,可以通过代理来调用 Adaptee,这样可以获得更大的灵活性。
(4)适配器模式和抽象工厂模式。
在适配器实现的时候,通常需要得到被适配的对象。如果被适配的是一个接口,那么就可以结合一些可以创造对象实例的设计模式,来得到被适配的对象示例,比如抽象工厂模式、单例模式、工厂方法模式等。
0
适配器模式(Adapter)---结构型的更多相关文章
- 适配器模式 adapter 结构型 设计模式(九)
现实世界中的适配器模型 先来看下来几个图片,截图自淘宝 上图为港版的插头与港版的插座 上图为插座适配器卖家的描述图 上图为适配后的结果 现实世界中适配器模式 角色分类 这就是适配器模式在电 ...
- 设计模式06: Adapter 适配器模式(结构型模式)
Adapter 适配器模式(结构型模式) 适配(转换)的概念无处不在:电源转接头.电源适配器.水管转接头... 动机(Motivation)在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象 ...
- Java设计模式06:常用设计模式之适配器模式(结构型模式)
1. Java之适配器模式(Adapter Pattern) (1)概述: 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类,可以在一起 ...
- C#设计模式--适配器模式(结构型模式)
一.适配器模式介绍: 适配器模式:将一个类的接口,转换成客户希望的另外一个接口.adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作 例子分析(充电器充电): 模式中的角色: 安 ...
- 设计模式之适配器模式(Adapter)
适配器模式原理:适配器模式属于结构型模式,主要作用是完成功能的转换, 1.通过一个类继承目标类. 2.需要适配的类 3.适配器 代码如下: #include <iostream> usin ...
- 设计模式(五)适配器模式Adapter(结构型)
设计模式(五)适配器模式Adapter(结构型) 1. 概述: 接口的改变,是一个需要程序员们必须(虽然很不情愿)接受和处理的普遍问题.程序提供者们修改他们的代码;系统库被修正;各种程序语言以及相 ...
- C#设计模式之七适配器模式(Adapter)【结构型】
一.引言 从今天开始我们开始讲[结构型]设计模式,[结构型]设计模式有如下几种:适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式.[创建型]的设计模式解决的是对象创建的问题, ...
- C#设计模式之六适配器模式(Adapter Pattern)【结构型】
一.引言 从今天开始我们开始讲[结构型]设计模式,[结构型]设计模式有如下几种:适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式.[创建型]的设计模式解决的是对象创建的问题,那[ ...
- NET设计模式 第三部分 结构型模式(7):适配器模式(Adapter Pattern)
适配器模式(Adapter Pattern) ——.NET设计模式系列之八 Terrylee,2006年2月 概述 在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但 ...
- 初探Java设计模式2:结构型模式(代理模式,适配器模式等)
行为型模式 行为型模式关注的是各个类之间的相互作用,将职责划分清楚,使得我们的代码更加地清晰. 策略模式 策略模式太常用了,所以把它放到最前面进行介绍.它比较简单,我就不废话,直接用代码说事吧. 下面 ...
随机推荐
- 小菜鸟之SSM框架
# SSM框架 # **什么是框架** 就是模板,将一些基础性的程序和代码由框架模板提供,然后程序员补充和业务需求相关的代码. # **ssm框架组成** s: springMvc 子框架 代替ser ...
- php静态调用非静态方法
<?php /** * php静态调用非静态方法 * author: 百里 * Date: 2019/7/18 * Time: 17:28 */ function dump(...$var) { ...
- 设置springmvc全局异常
设置全局异常,将异常信息指定内容展示给前端页面,保证程序的安全性 @Slf4j@Componentpublic class ExceptionResolver implements HandlerEx ...
- NOIP 2018 提高组初赛试题 题目+答案+简要解析
一.单项选择题(共 10 题,每题 2 分,共计 20 分: 每题有且仅有一个正确选项) 1. 下列四个不同进制的数中,与其它三项数值上不相等的是( ). A. (269) 16 B ...
- 【Trie】The XOR Largest Pair
[题目链接] https://loj.ac/problem/10050 [题意] 给出n个数,其中取出两个数来,让其异或值最大. [题解] 经典的01字典树问题. 首先需要把01字典树建出来. 然后对 ...
- 关于DB2的使用(DB2数据命令)
公司所用的数据库有金仓和DB2 首先要用命令窗口直接打开db2需要在cmd中输入:db2cmd 1:启动DB2数据库:db2start 2:连接数据库:db2 connect to 数 ...
- golang随机数及pipe
var pipe1 = make(chan int, 1000) func piTest(){ for{ data := <- pipe1 fmt.Printf("get data:% ...
- 以前面试 经常写这种 问掉的 copy 还是 =
get的时候,生成的 那个对象赋值给aa 生成的对象在这条语句完 就析构了: https://blog.csdn.net/qq_31759205/article/details/80544468h ...
- 牛客 203B tree(树形dp)
大意: 给定树, 对于每个节点, 求包含该节点的连通子集数. 显然有$dp[x]=\prod (dp[y]+1), ans[x]=(\frac{ans[fa[x]]}{dp[x]+1}+1)dp[x] ...
- 怎样监听HTTP请求的发出与完成
1. 监听HTTP请求发出的事件是: xhr.onloadstart 2. 监听HTTP请求结束的事件是: xhr.onloadend xhr.onloadstart = function() { / ...