大牧絮叨设计模式:适配器模式
文章目录
- 1、 `适配器模式`概述
- 1.1、 什么是适配器模式
- 1.2、 适配器模式的优点缺陷
- 2、 `Java`实现
- 2.1、 目标类:`Power`接口
- 2.2、 消费类:`Alienware`类型
- 2.3、 服务类:`China/America/Japan`提供电源供电
- 2.4、适配器:`ChinaAdapter`适配电脑供电
- 2.5、 适配器的使用
- 2.6、 小总结
- 3、 `Python`实现
- 4、 `Go`实现
1、 适配器模式
概述
适配器(Adapter
)[GOF95
]是一种类型之间互相协作的结构模式,旨在将使用服务的客户方的期望接口,通过适配的适配得到和服务方提供服务的接口相同的实现。
注意:很多资料中都是基于服务端来讲解适配器模式的。
本篇文章中,我们将会带领大家从服务端、客户端两个方面理解什么是适配器,怎么操作适配器。
1.1、 什么是适配器模式
BGM:大雄最近购买了一个笔记本,打算出国旅游。 DX:机器猫,一起出发去国外玩啦,好久没有出去过了呢! |
|
JQM:好呀好呀,时间不早了,现在就出发吧,带上你用的所有的东西哈,出国了可不比国内。 | |
DX:早就带好啦,不过话说我遇到一个问题,我的笔记本电脑是咱们大天朝电源适配器,去了国外能用吗? | |
JQM:这你就OUT了吧,直接跟厂家联系,让给你再发一个X国的笔记本电脑的电源适配器不就好啦。 | |
DX:我知道啊,但是有个小问题,厂家怎么知道X国的电压是多少,它们怎么给我发合适的笔记本电源呢? | |
JQM:你个山炮,电源电压就是一种通用规范 所有国家都按照自己国家的情况进行实现 虽然作为提供服务的一方他们每个国家的电压都不一样,但是只要他们满足通用规范就好啦。 |
|
JQM:而笔记本电脑制作商他们是知道这样的规范的,电脑制作商造出来电脑,要使用电源。所以电脑制作商和你是一边的,相当于使用电压服务的消费者,根据通用的规范造出来适合每个国家的电源适配器就好啦呀。 | |
DX:我好想明白了,提供服务的多个国家,每个国家的电压不同,但是都是提供了电压服务。我自己的笔记本需要电源,只需要我自己用合适的适配器来匹配对应国家的电压就可以了。 | |
JQM:孺子可教也,就是这么个道理。 提供服务的一方: 通用规范【电源电压】已经存在。 每个国家~具体【电源电压】已经实现。 消费服务的一方: 通用规范【电源电压】已经存在 按照【电源电压】规范找到合适的适配器就可以啦。 |
|
DX:明白了,适配器实现有两种情况: 第一种是由服务端实现,也就是每个国家直接给消费者提供好了转换器,这样的话使用服务的消费者得到了便捷,毕竟服务方就那么多,但是消费者千千万。 第二种是由消费方实现,服务方提供统一的服务,不同的 消费者根据自己的情况找到适合自己的适配器是使用服务端提供的服务。 |
|
JQM:是的,两种方式通常应用在不同的场合: 如果是通用功能,一个公司定义接口规范,多个公司进行具体实现的话,会选择第一种方式,比如 JDBC 的实现就是这样的方式。如果面向服务的模块化项目开发,通常服务端提供的服务接口就会是统一接口,而调用该服务的其他模块需要按照自己的调用方式自己实现适配过程。 |
如图所示:每个电脑产品Alienware
中都内聚了一个电源Power
,只需要使用电源供电usePower()
的方法即可,具体使用的是哪个国家的供电产品,依赖于当前项目中导入的是哪个具体国家的接口适配器Country
的实现。
下图中服务方式具体的China
、America
、Japan
,适配器Country
是将服务适配/转换为客户端Alienware
期望的接口Power
的实现。这就是适配器模式。
1.2、 适配器模式的优点缺陷
优点:
- 目标类
Power
和适配类China
进行了解耦合 - 增加了目标类
Power
的通用性,提高了适配类Country
的复用性 - 增强了程序结构的灵活性和扩展性
缺陷:
- 适配器
Country
和具体适配类China
,不论是单继承方式或者聚合的方式,耦合度都比较高。
2、 Java
实现
2.1、 目标类:Power
接口
Power
接口,表示的是上述案例中的电源规范,笔记本电脑需要电源,国家供电的服务就是电源。
package com.damu.inter;/*** <p>项目文档: 电源接口规范 </p>** @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>* @version V1.0*/
public interface Power {/*** 使用电源供电*/void usePower();
}
2.2、 消费类:Alienware
类型
Alienware
电脑是大雄的笔记本,笔记本要附带一个电源,所以将Power
内聚到了Alienware
类型中。
package com.damu.consumer;import com.damu.inter.Power;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.experimental.Accessors;/*** <p>项目文档: 外星人电脑 具体产品 </p>** @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>* @version V1.0*/
@Data
@Accessors(chain = true)
@AllArgsConstructor
public class Alienware {private Power power;/*** 电脑工作*/public void working() {// 电源供电power.usePower();// 电脑工作System.out.println("电脑正在工作中...");}
}
2.3、 服务类:China/America/Japan
提供电源供电
package com.damu.country;/*** <p>项目文档: 天朝上国</p>** @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>* @version V1.0*/
public class China {public void power220() {System.out.println("天朝上国供电:220V");}
}
package com.damu.country;/*** <p>项目文档: M国 </p>** @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>* @version V1.0*/
public class America {public void power110() {System.out.println("M国供电电压:110V");}
}
package com.damu.country;/*** <p>项目文档: 小岛国</p>** @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>* @version V1.0*/
public class Japan {public void power100() {System.out.println("小岛国供电:100V");}
}
2.4、适配器:ChinaAdapter
适配电脑供电
适配器ChinaAdapter
就是一个电源的具体实现,所以要实现Power
接口,同时它要完成供电方法的具体工作,所以通过继承(也可以通过内聚)的方式调用具体供电国家的供电方法,供电方法中实现了方法的转换调用,而这个转换调用,就是具体的适配过程,也是适配器模式的核心思想:将服务接口转换成客户需要的接口,转换过程就是适配过程
package com.damu.adapter;import com.damu.country.China;
import com.damu.inter.Power;/*** <p>项目文档: 天朝适配器 相当于图解中的Country</p>** @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>* @version V1.0*/
public class ChinaAdapter extends China implements Power {@Overridepublic void usePower() {// 适配方法中进行调用转换super.power220();}
}
package com.damu.adapter;import com.damu.country.America;
import com.damu.inter.Power;/*** <p>项目文档: M国适配器 相当于图解中的Country </p>** @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>* @version V1.0*/
public class AmericaAdapter extends America implements Power {@Overridepublic void usePower() {// 方法调用适配转换super.power110();}
}
2.5、 适配器的使用
package com.damu.main;import com.damu.adapter.AmericaAdapter;
import com.damu.adapter.ChinaAdapter;
import com.damu.consumer.Alienware;
import com.damu.inter.Power;/*** <p>项目文档: 测试类 </p>** @author <a href="https://github.com/laomu/laomu.github.io">大牧</a>* @version V1.0*/
public class Main {public static void main(String[] args) {// 根据引入的适配器创建对应的适配对象
// Power power = new ChinaAdapter(); // 大雄在天朝Power power = new AmericaAdapter(); // 大雄出国,更换电源适配器// 创建电脑对象Alienware alienware = new Alienware(power);// 电脑接电工作alienware.working();}
}
2.6、 小总结
需要注意的是,在适配器模式
中
- 目标接口
Power
规范了调用者调用的方法
以及适配器需要转换后的方法
- 调用者
Alienware
和服务提供者China
之间解耦合
- 调用者
3、 Python
实现
Python
由于同时支持函数式编程和面向对象的设计,所以实现方式非常多,我们这里模拟Java
的实现通过类型接口的方式做一版实现
"""
适配器模式
"""
import abcclass Power(metaclass=abc.ABCMeta):"""电源规范"""def power(self):raise("该方法必须实现")class Computer:"""电脑产品"""def __init__(self, power):self.power = powerdef working(self):# 电源供电self.power.power()# 电脑工作print("扫毒2播放中....")class China:"""天朝上国"""def power220(self):print("220V供电中...")class ChinaAdapter(China, Power):"""适配器类型"""def __init__(self, *args, **kwargs):super(ChinaAdapter, self).__init__(*args, **kwargs)def power(self):"""供电方法"""# 调用国家供电方法super(ChinaAdapter, self).power220()# 其他国家供电 及 适配类型 这里不多写了if __name__ == "__main__":# 创建适配器power = ChinaAdapter()# 创建电脑computer = Computer(power)# 电脑工作computer.working()
4、 Go
实现
Go
中的接口的实现和继承关系,都是通过结构体内聚来完成的,适配器模式
代码如下:
package mainimport "fmt"/*电源接口规范*/
type Power interface{PowerSupply()
}/*电脑产品*/
type ComputerHuawei struct{Powername string
}func (computer ComputerHuawei) Working() {computer.PowerSupply()fmt.Println("电源正常供电,电脑开始工作")
}/*国家供电*/
type China struct {name string
}func (china China) Power220() {fmt.Print("天朝上国,220V供电中.")
}/* 适配器*/
type ChinaAdapter struct {ChinaPower
}func (chinaAdapter ChinaAdapter) PowerSupply() {// 调用国家供电chinaAdapter.Power220()
}func main() {// 创建适配器china := China{name:"中国"}adpater := ChinaAdapter{}adpater.China = china// 创建电脑computer := ComputerHuawei{name:"华为游戏本"}// 内聚电源适配器computer.Power = adpater// 正常工作computer.Working()
}
大牧絮叨设计模式:适配器模式相关推荐
- 大牧絮叨设计模式:抽象工厂模式
文章目录 1. 抽象工厂模式概述 1.1. 核心组件 1.2. 优点缺点 2. `Java`实现 2.1. 工厂及产品结构的定义 2.2. 具体工厂类的实现 3. `Python`实现 4. `Go` ...
- 大牧絮叨设计模式:简单工厂模式
文章目录 1. 简单工厂模式概述 1.1.简单工厂模式核心组件 1.2.简单工厂模式优缺点 2.` Java`实现 公共父类定义 产品具体实现类 简单工厂定义 代码运行测试: 3. `Python`实 ...
- 大牧絮叨设计模式:建造者模式
文章目录 1. `建造模式` 概述 1.1. 核心组件 1.2. 优点缺陷 2. `Java` 实现 2.1. 抽象建造者`Builder` 2.2. 内聚组件`Aggregation Product ...
- 大牧絮叨设计模式:原型模式
文章目录 1. `原型模式`概述 1.1. 核心组件 1.2. 优点缺陷 2. `Java`实现 2.1. 原型抽象 2.2. 原型实现 2.3. 原型对象管理器 2.4. 消费者 2.5. `深.浅 ...
- 大牧絮叨设计模式:单例模式
文章目录 1.单例模式概述 1.1. 核心组件 1.2. 优点缺陷 2. `Java`实现 2.1.饿汉式单例模式 2.2. 懒汉式单例模式 3. `Python`实现 3.1. 单实例操作 3.2. ...
- 大牧絮叨设计模式:工厂方法模式
文章目录 1. 工厂方法模式概述 1.1. 工厂方法模式核心组件 1.2. 工厂方法模式优缺点 2. `Java`实现 (1) 核心工厂声明 (2) 核心产品声明 (3) 产品具体实现 (4) 工厂具 ...
- 设计模式适配器模式_21世纪的设计模式:适配器模式
设计模式适配器模式 这是我的演讲的第三部分," 21世纪的设计模式" . 适配器模式桥接世界. 在一个世界中,我们有一个概念的界面. 在另一个世界,我们有不同的界面. 这两个接口有 ...
- Python设计模式-适配器模式
Python设计模式-适配器模式 基于Python3.5.2,代码如下 #coding:utf-8class ACpnStaff:name = ""id = "" ...
- Java | 设计模式-适配器模式
继代理模式后又来到适配器模式啦,想看之前的也有哦.持续更新中哦.让我们一起加油吧兄弟们,干他. 很喜欢一句话:"八小时内谋生活,八小时外谋发展". 你好,如果喜欢,请一起坚持!! ...
最新文章
- java合并list_java合并list方法代码实例
- 阿里云高级技术专家带你全面了解云主机性能评测
- python递归的方式打印九九乘法表
- MySQL------存储过程的使用
- 卧槽!Intellij IDEA中竟然有这么多炫酷的插件,啪啪啪~
- 垃圾分类:真正的麻烦在于怎样处理
- 毕设题目:Matlab树叶识别
- 删除excel中复制网页带过来的下拉框、复选框、单选框
- 食品和饮料销售预测分析
- 使用Windows平台的VS2022来调试AKStream
- 数字电路 时序逻辑电路
- Deepin重装Win10
- 中创教育提示:教育机构主动退费?警惕落入退费诈骗陷阱!
- 巧用 Redis Hyperloglog,轻松统计 UV 数据
- [游戏记录]滚动的天空
- LiveNVR配置拉转RTSP传统海康大华安防摄像机直播流输出RTSP/RTMP/HLS/HTTP-FLV如何获取直播流地址
- PLC模拟量输入 模拟量转换FB S_ITR(三菱FX3U)
- 混音 文件 生成 linux,linux 混音
- C专家编程 第11章 你懂得C,所以C++不再话下 11.13 多态---运行时绑定
- 朱建平:如何架构海量存储系统(附视频回放)
热门文章
- 爬虫实战3:模拟登陆知乎并爬取任意帖子数据
- 转:2018年教育部《关于面向中小学生的全国性竞赛活动管理办法(试行)》文件通知
- 恶意软件通杀 Win、macOS、Linux 三大系统;唱片巨头起诉 Youtube-dl 的托管服务商;2022 年不是 Linux 桌面元年 | 开源日报
- (清华毕业生)大佬总结的“大数据”学习路线+教程
- 扫雷自定义最难C语言,C语言实现扫雷小游戏(扩展版可选择游戏难度)
- 项目模板下载推荐网站
- 360,谷歌浏览器登录管家帐户密码查看
- 【css】LCD液晶字体——自定义字体@font-face
- opencv眼动识别(2_眼动识别)
- gitlab仓库和mysql_GitLab版本管理-自建git仓库