李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
再论适配器设计模式
Leefs
2019-10-23 AM
1376℃
0条
## 再论适配器设计模式 ### 前言 在《Java编程思想》这本书中对适配器设计模式讲解的不是太清晰,于是乎小编就在网上搜了一些大佬的资料,然后进行了一些整理,希望对大家有所帮助。 ### 一、适配器设计模式概念 #### 1. 适配器模式的定义 将一个类的接口转成客户期望的另一个接口。 适配器模式使得原本由于接口不匹配而不能一起工作的那些类可以一起工作 。 #### 2. 适配器模式结构图 ![适配器模式结构图.png][1] 图1. 适配模式结构图 来源网络 **Adeptee**:服务端写的接口 **Target**:客户端所要期待访问的接口 我们总不能为了适应客户端去修改自己服务端的接口,这个时候就需要一个中间进行转化的步骤,希望写一个方法,能够实现在既不改变自己服务端接口的前提下还能满足客户端的需求。 这时候就需要写一个适配器Adapter,将Adeptee转化成客户端能访问的接口。 **通过适配器Adapter,用户端就可以访问Adaptee。** #### 3. 适配器模式分类 1. 1.类的适配器模式 2. 2.对象的适配器模式 3. 3.接口的适配器模式 ### 二、适配器示例 #### 1. 使用场景举例 手机想要投影到投影仪上,由于手机是Type-c接口,投影仪是VGA接口。不能直接投影,需要一个适配器,将视频信号从Type-c口转到VGA口,最后才能输出到大屏幕上。 ![Typec转VGA.png][2] 图2. typec转vga/hdm转换器 来源网络 如图所示,这有一个适配器,一号口是typec口,二号口是vga口,只有将视频信号从typec口输入,转换输出到vga口,才能和投影仪对接,实现手机屏幕投影到投影仪上的任务。**涉及的物品有:手机、适配器、投影仪。** #### 2.代码实现 2.1 定义一个手机,它有个typec口,这是视频源。 ```java public class Phone { public void typecPhone() { System.out.println("信息从Typec口的手机输出。"); } } ``` 2.2 定义一个vga接口 ```java public interface Vga { void vgaInterface(); } ``` **2.3 类的适配器模式** ```java public class Typec2Vga1 extends Phone implements Vga{ @Override public void vgaInterface() { // TODO Auto-generated method stub typecPhone(); System.out.println("接收到Type-c口信息,信息转换成VGA接口中..."); System.out.println("信息已转换成VGA接口,显示屏可以对接。"); } } ``` 2.4 主函数 ```java public class Screen { public static void main(String[] args) { //第一种适配器用法 System.out.println("-------------第一种适配器------------"); Vga vga = new Typec2Vga1(); vga.vgaInterface();//适配器将typec转换成vga System.out.println("显示屏对接适配器,手机成功投影到显示屏!"); } } ``` > 运行结果 ```java -------------第一种适配器------------ 信息从Typec口的手机输出。 接收到Type-c口信息,信息转换成VGA接口中... 信息已转换成VGA接口,显示屏可以对接。 显示屏对接适配器,手机成功投影到显示屏! ``` > 功能分析 + 1.类Phone拥有一个方法typecPhone()待适配,目标接口是Vga + 2.通过Typec2Vga1类,将Phone的功能扩展到Vga里 **原理:通过继承来实现适配器功能。** **2.5 对象的适配器模式** ```java public class Typec2Vga2 implements Vga{ private Phone phone; public (Phone phone) { // TODO Auto-generated constructor stub this.phone = phone; } @Override public void vgaInterface() { // TODO Auto-generated method stub if(phone != null) { phone.typecPhone(); System.out.println("接收到Type-c口信息,信息转换成VGA接口中..."); System.out.println("信息已转换成VGA接口,显示屏可以对接。"); } } } ``` 2.5 主函数 ```java public class Screen { public static void main(String[] args) { //第二种适配器用法 System.out.println("-------------第二种适配器------------"); Typec2Vga2 typec2Vga1 = new Typec2Vga2(new Phone()); typec2Vga1.vgaInterface();//适配器将typec转换成vga System.out.println("显示屏对接适配器,手机成功投影到显示屏!"); } } ``` > 运行结果 ```java -------------第二种适配器------------ 信息从Typec口的手机输出。 接收到Type-c口信息,信息转换成VGA接口中... 信息已转换成VGA接口,显示屏可以对接。 显示屏对接适配器,手机成功投影到显示屏! ``` > 功能分析 + 1.Typec2Vga2类实现Vga接口,不再去继承Phone类进行扩展,而是持有Phone的实例,达到解决兼容性的问题。 + 2.在Typec2Vga2中加入Phone类的对象实例,可以直接通过new Phone()对象的方式进行参数传递 + 3.在Typec2Vga2的构造方法中接收Phone传递来的对象实例 **原理:通过组合方式来实现适配器功能。** **2.6 接口的适配器模式** ```java /** * 定义接口 */ public interface Target { void typec(); void typec2vga(); void typec2hdmi(); } ``` 2.7 定义一个抽象类 ```java public abstract class Adapter implements Target{ public void typec() { } public void typec2vga() { } public void typec2hdmi() { } } ``` 2.8 实现一个VGA适配器 ```java public class VgaAdapter extends Adapter{ public void typec() { System.out.println("信息从Typec口的手机输出。"); } public void typec2vga() { System.out.println("接收到Type-c口信息,信息转换成VGA接口中..."); System.out.println("信息已转换成VGA接口,显示屏可以对接。"); } } ``` 2.9 主函数 ```java public class Screen { public static void main(String[] args) { //第三种适配器用法 System.out.println("-------------第三种适配器------------"); VgaAdapter vgaAdapter = new VgaAdapter(); vgaAdapter.typec(); vgaAdapter.typec2vga();//适配器将typec转换成vga System.out.println("显示屏对接适配器,手机成功投影到显示屏!"); } } ``` > 运行结果 ```java -------------第三种适配器------------ 信息从Typec口的手机输出。 接收到Type-c口信息,信息转换成VGA接口中... 信息已转换成VGA接口,显示屏可以对接。 显示屏对接适配器,手机成功投影到显示屏! ``` > 功能分析 + 1.定义一个接口Target + 2.当我们只需要Target接口中的typec()方法和typec2vga()方法,我们用不上其中的typec2hdmi()方法时 + 3.接下来定义一个抽象类Adapter实现Target接口,实现接口中的所有方法 + 4.当我们需要这个接口中的方法时,可以通过中间层抽象类来实现,不和接口直接打交道 + 5.VgaAdapter类继承抽象类Adapter,并重写需要的typec()方法和typec2vga()方法 有时我们写的一个接口中有多个抽象方法,当我们写该接口的实现类时,必须实现该接口的所有方法,这明显有时比较浪费,因为并不是所有的方法都是我们需要的,有时只需要某一些,此处为了解决这个问题,我们引入了接口的适配器模式,借助于一个抽象类,该抽象类实现了该接口,实现了所有的方法,而我们不和原始的接口打交道,只和该抽象类取得联系,所以我们写一个类,继承该抽象类,重写我们需要的方法就行。 **原理:借助抽象类来实现适配器功能。** ### 总结 1. 1.当希望将一个类转换为满足另一个新接口的类时,可以使用**类的适配器模式**,创建一个新类,继承原有的类,实现新的接口即可。 2. 2.当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个Typec2Vga2 类,持有原类的一个实例,在Typec2Vga2 类的方法中,调用实例的方法就行。 3. 3.当不希望实现一个接口中所有的方法时,可以创建一个抽象类Adapter ,实现所有方法,我们写别的类的时候,继承抽象类即可。 *附:[参考原文连接](https://www.cnblogs.com/luohanguo/p/10334291.html)* [1]: https://lilinchao.com/usr/uploads/2019/10/3414631424.png [2]: https://lilinchao.com/usr/uploads/2019/10/888342759.png
标签:
Java
,
Java编程思想
,
JavaSE
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://www.lilinchao.com/archives/49.html
上一篇
多表查询
下一篇
类和接口的嵌套(一)
取消回复
评论啦~
提交评论
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
标签云
Stream流
JavaWEB项目搭建
Map
Scala
Jquery
Azkaban
二叉树
NIO
DataWarehouse
数据结构和算法
FastDFS
链表
Netty
容器深入研究
Yarn
高并发
Thymeleaf
GET和POST
Beego
Spark RDD
Python
队列
工具
Kibana
人工智能
FileBeat
Sentinel
机器学习
Zookeeper
Hadoop
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞