Java设计模式--适配器模式详解

目录
  • 定义
  • 结构
  • 示例
  • 扩展
  • 总结

定义

适配器模式用于解决接口间的兼容问题。

当我们需要使用某个类提供的接口,但是这个接口与现在的系统需求不符,由于该接口是由第三方提供的,或者是已经在生产上跑了很久的存量类,我们不想通过改变这个类来满足现在系统的需求,那么这时候就可以考虑通过将目标类封装成一个满足系统需求的新类,因此适配器(Adapter)也称为包装器(Wrapper)。

结构

适配器模式包含如下角色:

  • Target:目标抽象类,客户类期望的接口。
  • Adapter:适配器类,适配器模式的核心,实现目标抽象类和适配者类的转换。
  • Adaptee:适配者类,与目前需求不兼容的类,即需要被包装的类。
  • Client:客户类,调用在目标抽象类中定义的业务方法。

适配器模式有类适配器和对象适配器两种实现:

1、在类适配器模式中,适配器类实现了目标抽象类接口并继承了适配者类,在目标抽象类的实现方法中调用所继承的适配者类的方法。

2、在对象适配器模式中,适配器类实现了目标抽象类并定义了一个适配者类的对象实例,在目标抽象类的实现方法中调用适配者类实例的方法。

示例

假如我们手上有一只手机,它只有一个type-c接口,同时手上有一条3.5mm的耳机,想听音乐的时候就会发现二者不兼容,相较于更换手机或者耳机,一般我们会选择一条type-c和3.5mm的转接线来实现最高性价比。

此时将3.5mm耳机比作客户端(客户类),它期望得到音乐信号的目标是3.5mm接口(目标抽象类),type-c接口则是手机提供的音乐信号传输接口(适配者类),与耳机接头不兼容,而转接线(适配器类)可以将type-c接口包装为耳机可以插入的3.5mm接口,能够解决手机与耳机的不兼容问题,实现用耳机接收手机播放的音乐信号。

1、定义目标抽象类,即客户类期望的接口。

public interface ThreePointFiveConn {
	//一个提供音乐的3.5mm接口
	public void playMusic(String connector);
}

2、定义适配者类,即需要被包装的类。

public interface PlayMusicConn {
	public void playMusicOut(String connector);
}
public class TypecPlayMusicConn implements PlayMusicConn {
	//只允许typec接头插入
	public void playMusicOut(String phoneConnType, String musicName) {
		if("typec".equals(phoneConnType)){
			//实现播放音乐功能
			System.out.println("playing music with typec Player..." + musicName);
		}else {
			System.out.println("error!");
		}
	}
}
public class LightningPlayMusicConn implements PlayMusicConn {
	//只允许Lightning接头插入
	public void playMusicOut(String phoneConnType, String musicName) {
		if("lightning".equals(phoneConnType)){
			//实现播放音乐功能
			System.out.println("playing music with lightning Player..." + musicName);
		}else {
			System.out.println("error!");
		}
	}
}

类适配器模式:由于适配器类是适配者类的子类,因此可以在适配器类中重写适配者类的方法,使得适配器类更具灵活性。

3、构建适配器类,将适配者类PlayMusicConn包装为目标抽象类ThreePointFiveConn的一个子类。

public class Transverter extends TypecPlayMusicConn implements ThreePointFiveConn {
	//调用继承的适配者类的方法
	public void playMusic(String musicName) {
		super.playMusicOut("typec", musicName);
	}
}

4、客户端类(耳机)使用

public class EarPhone {
	public static void main(String[] args) {
		ThreePointFiveConn earPhone = new Transverter();
		earPhone.playMusic("Hey Jude");
	}
}

运行结果:

playing music with typec Player…Hey Jude

  • 对象适配器模式:一个对象适配器类可以把多个不同的适配者类及其子类适配到同一个目标抽象类,因此具有更大的兼容性。

3、构建适配器类,将适配者类PlayMusicConn包装为目标抽象类ThreePointFiveConn的一个子类。

public class Transverter implements ThreePointFiveConn {
	//定义适配者类的对象实例
	private PlayMusicConn playMusicConn;
	public Transverter(PlayMusicConn playMusicConn){
		this.playMusicConn = playMusicConn;
	}
	public void playMusic(String musicName) {
		if(playMusicConn instanceof TypecPlayMusicConn) {
			playMusicConn.playMusicOut("typec", musicName);
		}else if(playMusicConn instanceof LightningPlayMusicConn) {
			playMusicConn.playMusicOut("lightning", musicName);
		}else {
			System.out.print("error!");
		}
	}
}

4、客户端类(耳机)使用

public class EarPhone {
	public static void main(String[] args) {
		//typec接口手机播放音乐
		ThreePointFiveConn earPhone = new Transverter(new TypecPlayMusicConn());
		earPhone.playMusic("Hey Jude");
		//lightning接口手机播放音乐
		ThreePointFiveConn earPhone1 = new Transverter(new LightningPlayMusicConn());
		earPhone1.playMusic("Hey Jude");
	}
}

运行结果:

playing music with typec Player…Hey Jude
playing music with lightning Player…Hey Jude

扩展

除类适配器和对象适配器模式外,还有一种接口适配器模式。接口适配器模式是指在定义适配器时,先将其定义为一个抽象类实现接口,接口中定义了多个抽象方法,定义该适配器的子类时,子类只实现其中的部分抽象方法。

它适用于一个接口不想使用其所有的方法的情况。因此也称为单接口适配器模式。

public abstract class TransverterInterface implements ThreePointFiveConn {
	PlayMusicConn playMusicConn = new TypecPlayMusicConn();
	public void playMusic(String musicName) {
		playMusicConn.playMusicOut("typec", musicName);
	}
	public void anotherMethod1(){}
	public void anotherMethod2(){}
}
public class TransverterInterfaceImpl extends TransverterInterface {
	public void playMusic(String musicName) {
		super.playMusic(musicName);
	}
}

总结

适配器模式的主要优点是将目标类和适配者类解耦,增加了类的透明性和复用性,同时系统的灵活性和扩展性都非常好,更换适配器或者增加新的适配器都非常方便,符合“开闭原则”。

适配器模式适用情况包括:系统需要使用现有的类,而这些类的接口不符合系统的需要;想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类一起工作。

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • Java设计模式之Adapter适配器模式

    一.场景描述 "仪器数据采集器"包含采集数据以及发送数据给服务器两行为,则可定义"仪器数据采集器"接口,定义两方法"采集数据capture"和"发送数据sendData". "PDF文件数据采集器"实现时,要实现"仪器数据采集器"接口,实现"采集数据"方法:目前有"PDF文件内容解析工具"类PdfFileExtractor,该类实现PDF文件的数据

  • 23种设计模式(5) java适配器模式

    23种设计模式第五篇:java适配器模式 定义: 将一个类的接口转换成客户希望的另外一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 角色: 目标(Target)角色:这就是所期待得到的接口,也就是这类的接口是符合我们要求的. 源(Adapee)角色:我们要使用的接口,但是这个接口不符合我们的要求,也就是现在需要适配的接口. 适配器(Adaper)角色:适配器类是适配器模式的核心.适配器把源接口转换成目标接口.显然,这一角色不可以是接口,而必须是具体类. 分类: 1

  • java设计模式笔记之适配器模式

    适配器(Adapter)模式: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 生活中的场景: 1.笔记本电源适配器,可以将220v转化为适合笔记本使用的电压. 2.给笔记本电脑的usb接口插入台式机的ps/2接口的键盘,需要一个usb和ps/2的接口转接器,此时usb和ps/2的接口转接器就充当了适配器的角色. 通用类图: 在上面的通用类图中,Cient 类最终面对的是 Target 接口(或抽象类),它只能够使用符合这一

  • java设计模式之浅谈适配器模式

    一.结构型模式 结构型模式有什么好处? 从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题 二.适配器模式 USB网线转换器 三.什么是适配器模式? 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本接口不兼容而不能一起工作的那些类能够变得在一起工作! 四.角色分析 目标接口:客户所期待的接口,目标可以是具体的或抽象的类,也可以是接口 需要适配的类:需要适配的类或适配者类 适配器:通过包装一个需要适配的对象,把原接口转换成目标对象! 例子: 适配的类:网线

  • java中设计模式之适配器模式

    java中设计模式之适配器模式  前言: 适配器模式可以将一个类或接口应用于另一个不同但是却有联系的接口,主要的做法是通过声明一个目标接口的实现类,在该类中声明一个将被适配类或接口(被适配者)作为参数的构造器和被适配者的实例,这样在实现目标接口的时候就可以调用被适配者的实例,并且辅以一些额外的操作.适配器模式的主体有三个部分:适配者,适配者实现类和被适配者.具体类结构如下图: 这里将被适配者的对象以组合的方式放到适配器类中,那么被适配者及其实现者都可以使用该适配器.适配器模式的优点在于可以将不同

  • Java设计模式--适配器模式详解

    目录 定义 结构 示例 扩展 总结 定义 适配器模式用于解决接口间的兼容问题. 当我们需要使用某个类提供的接口,但是这个接口与现在的系统需求不符,由于该接口是由第三方提供的,或者是已经在生产上跑了很久的存量类,我们不想通过改变这个类来满足现在系统的需求,那么这时候就可以考虑通过将目标类封装成一个满足系统需求的新类,因此适配器(Adapter)也称为包装器(Wrapper). 结构 适配器模式包含如下角色: Target:目标抽象类,客户类期望的接口. Adapter:适配器类,适配器模式的核心,

  • Java设计模式—观察者模式详解

    观察者模式 包括这个模式在内的接下来的四个模式,都是类和类之间的关系,不涉及到继承,学的时候应该 记得归纳,记得本文最开始的那个图.观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一些博客或wiki时,经常会看到RSS图标,就这的意思是,当你订阅了该文章,如果后续有更新,会及时通知你.其实,简单来讲就一句话:当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是一种一对多的关系. 先来看看关系图: 我解释下这些类的作用:MySubject类就是我们的主对象,Obs

  • Java 设计模式之适配器模式详解

    目录 定义 结构图 使用场景 代码实现 Java代码实现 Python代码实现 定义 适配器将一个类的接口,转换成客户期望另一个接口.适配器让原本不兼容的类可以合作无间 结构图 如图所示,两脚插头如何能插入三脚插座,可以在中间加一个适配器进行转换,就能实现两脚插头能插入三脚插座. 使用场景 新的代码兼容旧的代码 使用别人好的代码到自己的代码中 代码实现 适配器模式有:对象适配器和类适配器 Java代码实现 java没有多继承,只能实现对象适配器 先创建两个接口 // 适配目标接口 public

  • Java结构型设计模式之适配器模式详解

    目录 适配器模式 分类 应用场景 优缺点 主要角色 类适配器 创建目标角色(Target) 创建源角色(Adaptee) 创建适配器(Adapter) 客户端调用 对象适配器 创建目标角色(Target) 创建源角色(Adaptee) 创建适配器(Adapter) 客户端调用 接口适配器 创建目标角色(Target) 创建源角色(Adaptee) 创建适配器(Adapter) 客户端调用 适配器模式 适配器模式(Adapter Pattern)又叫做变压器模式,属于结构型设计模式. 它的功能是将

  • Java之单例设计模式示例详解

    单例设计模式 保证一个类在内存中只能有一个对象. 思路: 1)如果其他程序能够随意用 new 创建该类对象,那么就无法控制个数.因此,不让其他程序用 new 创建该类的对象. 2)既然不让其他程序 new 该类对象,那么该类在自己内部就要创建一个对象,否则该类就永远无法创建对象了. 3)该类将创建的对象对外(整个系统)提供,让其他程序获取并使用. 饿汉式: 一上来我就把对象给你 new 好了,你来了直接就可以拿去"吃"了 懒汉式 (要是有人问单例的延迟加载方式指的就是这种方式) 一开始

  • PHP八大设计模式案例详解

    PHP命名空间 可以更好地组织代码,与Java中的包类似. Test1.php <?php namespace Test1;//命名空间Test1 function test(){ echo __FILE__; } Test2.php <?php namespace Test2; //命名空间Test2 function test(){ echo __FILE__;//打印当前文件所在的绝对路径. } Test.php <?php require 'Test1.php'; require

  • Java分层概念详解

    service是业务层 action层即作为控制器 DAO (Data Access Object) 数据访问 1.JAVA中Action层, Service层 ,modle层 和 Dao层的功能区分?(下面所描述的service层就是biz) 首先这是现在最基本的分层方式,结合了SSH架构.modle层就是对应的数据库表的实体类. Dao层是使用了Hibernate连接数据库.操作数据库(增删改查). Service(biz)层:引用对应的Dao数据库操作,在这里可以编写自己需要的代码(比如简

  • Java 反射机制详解及实例

    Java 反射机制详解及实例 反射,当时经常听他们说,自己也看过一些资料,也可能在设计模式中使用过,但是感觉对它没有一个较深入的了解,这次重新学习了一下,感觉还行吧!            一,先看一下反射的概念: 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 反射是Java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接.但是反射使用不当会成本很高

  • Java 类型信息详解和反射机制介绍

    RTTI RTTI(RunTime Type Information)运行时类型信息,能够在程序运行时发现和使用类型信息,把我们从只能在编译期知晓类型信息并操作的局限中解脱出来 传统的多态机制正是 RTTI 的基本使用:假设有一个基类 Shape 和它的三个子类 Circle.Square.Triangle,现在要把 Circle.Square.Triangle 对象放入 List<Shape> 中,在运行时,先把放入其中的所有对象都当作 Object 对象来处理,再自动将类型转换为 Shap

  • Kotlin与Java的区别详解

    什么是Kotlin? Kotlin是一种可以在 Java 虚拟机 (JVM) 上运行的开源编程语言.该语言可以在许多平台上运行. 它是一种将面向对象编程 (OOP) 和函数式编程结合在一个不受限制.自给自足且与众不同的平台中的语言. 什么是Java? Java 是一种多平台.面向对象.以网络为中心的编程语言.它是最常用的编程语言之一.它也用作计算平台,最早由 Sun Microsystem 于 1995 年发布,后来被 Oracle 公司收购. 主要区别: Kotlin 结合了面向对象和函数式编

随机推荐