适配器模式之对象适配器
问题导入:比如有A型螺母和B型螺母,那么用户可以再A型螺母上直接使用按着A型螺母生产的A型螺丝,同样也可以在B型螺母上直接使用按着B型 螺母标准生产的B型螺丝。但是由于A型螺母和B型螺母的标准不一样,用户在A型螺母上不能直接使用B型的螺丝,反之也一样。该如何达到这个目的呢?
使用适配器就可以解决这个问题:生产一种“A型螺母适配器”,这种A型螺母适配器的前端符合A型螺母标准要求,可以拧在A型螺母上,后端又焊接了一个B型螺母。这样用户就可以借助A型螺母适配器在A型螺母上使用B型的螺丝了。
适配器模式又称为包装器,是用来将一个类的接口转换成客户希望的另外一个接口。这可以使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。适配器模式的关键是建立一个适配器,这个适配器实现了目标接口并且包含了被适配者的引用。
适配器模式的三种角色:
一、目标:目标是一个接口,该接口是客户想要使用的接口。
二、被适配者:被适配者是一个已经存在的接口或抽象类,这个接口接口或者抽象类需要适配。
三、适配器:适配器是一个类,该类实现了目标接口并且包含有被适配者的引用,即适配器的职责是对适配者接口或抽象类与目标接口进行适配。
以下通过一个简单的问题来描述适配器模式中所涉及的各个角色。
用户已经有一个两厢的插座,但是最近用户又有了一个新的三厢插座。用户现有一台洗衣机和一台电视机,洗衣机是三厢插头,而电视机是两厢插头。现在用户想用心的三厢插座来使用洗衣机和电视机,即用心的三厢插座为洗衣机和电视机接通电流。
针对以上问题,使用适配器模式设计若干个类。
1.目标
本问题是使用三厢插座来为电视机和洗衣机接通电流,所以目标是三厢插座。把三厢插座设置为一个接口:
1 package com.adatpe;
2
3 //适配目标:三相插座
4 public interface ThreeElectricOutlet {
5 void connectElectricCurrent();
6 }
2.被适配者
对于本问题,用户是想要用三厢插座为两厢插头的电视机接通电流,所以被适配者应该是两厢插座,也设置为一个接口:
1 package com.adatpe;
2
3 //被适配者:两相插座
4 public interface TwoElectricOutlet {
5 void connectElectricCurrent();
6 }
3.适配器
该适配器实现了目标接口三厢插座ThreeElectricOutlet,同时又包含了两厢插座TwoElectricOutlet的引用:
1 package com.adatpe;23 //适配器:实现目标接口4 public class ThreeElectricAdapter implements ThreeElectricOutlet {5 //适配器包含被适配者的引用6 private TwoElectricOutlet outlet;7 public ThreeElectricAdapter(TwoElectricOutlet outlet) {8 this.outlet = outlet;9 }
10 public void connectElectricCurrent() {
11 outlet.connectElectricCurrent();
12 }
13
14 }
下列应用程序中,Application.java使用了适配器模式中所涉及的类,应用程序负责用Wash类创建一个对象来模拟一台洗衣机,使用TV类创建一个对象来模拟一台电视机
使用ThreeElectricOutlet接口变量调用Wash对象的connectElectricCurrent()方法,并借助适配器调用TV对象的connectElectricCurrent()方法,即用三厢插座分别为洗衣机和电视机接通电流。
1 package com.adatpe;23 public class Application {4 public static void main(String[] args) {5 ThreeElectricOutlet outlet; //目标接口(三相插座)6 Wash wash = new Wash(); //洗衣机7 outlet = wash; //洗衣机插在三相插座上8 System.out.println(“使用三相插座接通电流”);9 outlet.connectElectricCurrent(); //接通电流开始洗衣服
10 TV tv = new TV(); //电视机
11 ThreeElectricAdapter adapter = new ThreeElectricAdapter(tv); //把电视插在适配器上面
12 outlet = adapter; //再把适配器插在三厢插座上
13 System.out.println(“使用三厢插座接通电流”);
14 outlet.connectElectricCurrent(); //接通电流,开始播放电视节目
15 }
16 }
17
18 //洗衣机使用三相插座
19 class Wash implements ThreeElectricOutlet{
20 private String name;
21 public Wash() {
22 name = “黄河洗衣机”;
23 }
24 public Wash(String name){
25 this.name = name;
26 }
27 public void connectElectricCurrent() {
28 turnOn();
29 }
30 public void turnOn(){
31 System.out.println(name+”开始洗衣服了”);
32 }
33 }
34
35
36 //电视机使用两厢插座
37 class TV implements TwoElectricOutlet{
38 private String name;
39 public TV() {
40 name = “长江电视机”;
41 }
42 public TV(String name){
43 this.name = name;
44 }
45 public void connectElectricCurrent() {
46 turnOn();
47 }
48 public void turnOn(){
49 System.out.println(name+”开始播放电视节目”);
50 }
51
52 }
运行结果为:
使用三相插座接通电流
黄河洗衣机开始洗衣服了
使用三厢插座接通电流
长江电视机开始播放电视节目
下面举个双向适配器的例子
在适配器模式中,如果Adapter角色同时实现目标接口和被适配者接口,并包含目标接口和被适配接口的引用,那么该适配器就是一个双向适配 器。使用双向适配器,用户既可以用新的接口又可以用已有的接口。在以上例子中,如果用户希望能有三厢插座来接通洗衣机和电视机的电流,有可以用两厢插座来 接通洗衣机和电视机的电流,那么就必须使用一个双向适配器。具体代码如下:
1 package com.adatpe;23 public class ThreeAndTwoElectricAdapter implements ThreeElectricOutlet,4 TwoElectricOutlet {5 private ThreeElectricOutlet threeElectricOutlet;6 private TwoElectricOutlet twoElectricOutlet;7 public ThreeAndTwoElectricAdapter(ThreeElectricOutlet threeOutlet,TwoElectricOutlet twoOutlet) {8 threeElectricOutlet = threeOutlet;9 twoElectricOutlet = twoOutlet;
10 }
11 public ThreeAndTwoElectricAdapter(TwoElectricOutlet twoOutlet,ThreeElectricOutlet threeOutlet){
12 threeElectricOutlet = threeOutlet;
13 twoElectricOutlet = twoOutlet;
14 }
15 public void connectElectricCurrent() {
16 if(this instanceof ThreeElectricOutlet){
17 twoElectricOutlet.connectElectricCurrent();//twoElectricOutlet是被适配的接口
18 }
19 if(this instanceof TwoElectricOutlet){
20 threeElectricOutlet.connectElectricCurrent(); //threeElectricOutlet是被适配的接口
21 }
22 }
23 public static void main(String[] args) {
24 ThreeElectricOutlet threeOutlet;
25 TwoElectricOutlet twOutlet;
26 Wash wash = new Wash();
27 TV tv = new TV();
28 ThreeAndTwoElectricAdapter adapter = new ThreeAndTwoElectricAdapter(wash,tv);
29 threeOutlet = adapter;
30 System.out.println(“使用三厢插座接通电源”);
31 threeOutlet.connectElectricCurrent();
32 twOutlet = adapter;
33 System.out.println(“使用两厢插座接通电源”);
34 twOutlet.connectElectricCurrent();
35 }
36
37 }
运行结果为:
使用三厢插座接通电源
长江电视机开始播放电视节目
黄河洗衣机开始洗衣服了
使用两厢插座接通电源
长江电视机开始播放电视节目
黄河洗衣机开始洗衣服了
这样就实现了即可以用三厢插座又可以用两厢插座来为电视机和洗衣机接通电流了。
使用适配器模式主要有以下优点:
1.目标和被适配者是完全解耦的关系。
2.适配器模式满足“开–闭原则”,当添加一个实现了Adapter接口的新类时,不必修改Adapter,Adapter就能对这个新类的实例进行适配。
适配器模式之对象适配器相关推荐
- C++设计模式——适配器模式(对象适配器、类适配器)
http://blog.jobbole.com/109381/?winzoom=1 前言 现在的笔记本都只存在USB接口,用来口,电脑上存在的是USB接口,两者如何通信呢?可以使用USB转串口线连接电 ...
- 适配器模式(对象适配器)
适配器模式 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法在一起工作的两个类能够在一起工作. 适配器模式的两种形式 类适配器采用 "多继承" 的 ...
- 【设计模式】适配器模式 ( 类适配器代码模板 | 对象适配器代码模板 | 适配器模式示例 )
文章目录 I . 适配器模式 ( 类适配器 ) 代码模板 II . 适配器模式 ( 对象适配器 ) 代码模板 III . 适配器模式 代码示例 I . 适配器模式 ( 类适配器 ) 代码模板 1 . ...
- 【设计模式】适配器模式 ( 概念 | 适用场景 | 优缺点 | 外观模式对比 | 适配器模式相关角色 | 类适配器 | 对象适配器 | 实现流程 )
文章目录 I . 适配器模式概念 II . 适配器模式 适用场景 III . 适配器模式 优缺点 IV . 适配器模式 与 外观模式对比 V . 适配器模式 相关角色 ( 重点 ) VI . 适配器模 ...
- 适配器模式(类适配器,对象适配器,接口适配器)
现实生活中的适配器例子 泰国插座用的是两孔的(欧标),可以买个多功能转换插头(适配器) ,这样就可以使用了. 基本介绍 适配器模式(Adapter Pattern)将某个类的接口转换成客户端期望的另一 ...
- 适配器模式之类适配器与对象适配器的区别及代码实现
什么是适配器模式? 适配器模式(Adapter):直观理解就是使原来不能一起相互工作(接口不兼容)的两个功能通过Adapter兼容在一起. 类适配器和对象适配器 类适配器 Adapter 类继承Ada ...
- 设计模式--适配器模式 (类适配器和对象适配器)
适配器模式很常用的:商城中的例子比如快递发货,那么多种快递公司:可能每个快递公司的接口对接都不一样都要适配:比如各种框架中的类似以下思想的代码,都是为了适配. public function beha ...
- 适配器模式——类适配器模式,对象适配器模式
概述 如果去欧洲国家去旅游的话,他们的插座如下图最左边,是欧洲标准. 而我们使用的插头如下图最右边的.因此我们的笔记本电脑,手机在当地不能直接充电. 所以就需要一个插座转换器,转换器第1面插入当地的插 ...
- Java 设计模式 Adapter 对象适配器 模式
Java 设计模式 Adapter 对象适配器 模式 Adapter模式用于现有的程序无法直接使用,需要做适当的变换之后才能使用的情况. 涉及到的角色 Target对象:定义所需的方法. Client ...
最新文章
- Microsoft Exchange Server 2010测试四成员DAG
- [leetcode] 367. Valid Perfect Square
- Hadoop中shuffle阶段流程分析
- Bringing up interface eth0: Error: Unknown connection: 0e4faef8-9838-4a5d-8d08-47ed5e4415c7.
- Github大热论文 | U-GAT-IT:基于GAN的新型无监督图像转换
- HDU 2328 Corporate Identity
- 荣耀30S正式发布!荣耀赵明回应红米叫板:被强行捆绑,不太想搭理
- 《软件需求十步走》阅读笔记一
- 学习Altas 笔记[js调用重载的方法出错,如何处理]
- mac下修改MySQL密码
- 配置核查保密检查等保工具箱态势感知
- c语言求符合给定条件的整数集,中国大学MOOC-翁恺-C语言程序设计习题集(二)...
- 苏宁易购关键词搜索商品方法
- 央行房贷新政带火北京学区房:相比前两月涨10%
- At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger
- Spring AOP基础组件 Advised
- B - Restore Modulo
- 安卓获取手机唯一码工具类
- 中国新冠疫情数据可视化
- CEC循环生态社区答疑XAG到底有多好的价值前景