制作网站的列子,一个网站绑定两个域名,室内设计效果图价格,物流管理网站建设适配器模式#xff08;Adapter Pattern#xff09;是一种结构型设计模式#xff0c;它通过将一个类的接口转换成客户期望的另一个接口#xff0c;使得原本接口不兼容的类可以一起工作。在Java中#xff0c;适配器模式可以通过实现一个适配器类来实现两个不兼容接口之间的转…适配器模式Adapter Pattern是一种结构型设计模式它通过将一个类的接口转换成客户期望的另一个接口使得原本接口不兼容的类可以一起工作。在Java中适配器模式可以通过实现一个适配器类来实现两个不兼容接口之间的转换。
各角色定义
在适配器模式中通常会涉及以下四种角色
目标Target 定义客户端所期望的接口。可以是具体的类或者抽象类。适配者Adaptee 拥有一个已经存在的接口该接口与目标接口不兼容。这个已有的接口通常是一个没有继承和实现关系的旧接口。适配器Adapter 充当适配器的角色实现目标接口。 持有适配者的实例通过适配者来实现目标接口的方法。负责将适配者的功能转换为目标接口期望的形式。客户端Client 使用目标接口来调用适配器的方法。客户端只知道目标接口并不知道适配器和适配者的存在。
以上如图所示
Target类表示目标接口它有一个request()方法。Adaptee类表示已有的不兼容接口它有一个specificRequest()方法。Adapter类是适配器它实现了Target接口并持有一个Adaptee实例。在request()方法中调用Adaptee的specificRequest()方法来实现适配。
具体示例
下面我们介绍使用适配器来播放不同类型的音频文件的代码示例
定义客户端需要的接口比如播放指定类型的音频文件入参是文件类型和文件名称
public interface MediaPlayer {void play(String audioType, String fileName);
}一个已有的接口Adaptee和实现类
public interface AdvancedMediaPlayer {void playVlc(String fileName);void playMp4(String fileName);
}
public class VlcPlayer implements AdvancedMediaPlayer {Overridepublic void playVlc(String fileName) {System.out.println(Playing vlc file. Name: fileName);}Overridepublic void playMp4(String fileName) {// Do nothing}
}public class Mp4Player implements AdvancedMediaPlayer {Overridepublic void playVlc(String fileName) {// Do nothing}Overridepublic void playMp4(String fileName) {System.out.println(Playing mp4 file. Name: fileName);}
}创建适配器类Adapter实现目标接口并持有已有接口的实例
public class MediaAdapter implements MediaPlayer {private AdvancedMediaPlayer advancedMediaPlayer;public MediaAdapter(String audioType) {if (audioType.equalsIgnoreCase(vlc)) {advancedMediaPlayer new VlcPlayer();} else if (audioType.equalsIgnoreCase(mp4)) {advancedMediaPlayer new Mp4Player();}}Overridepublic void play(String audioType, String fileName) {if (audioType.equalsIgnoreCase(vlc)) {advancedMediaPlayer.playVlc(fileName);} else if (audioType.equalsIgnoreCase(mp4)) {advancedMediaPlayer.playMp4(fileName);}}
}使用适配器模式
public class AudioPlayer implements MediaPlayer {private MediaAdapter mediaAdapter;Overridepublic void play(String audioType, String fileName) {if (audioType.equalsIgnoreCase(mp3)) {System.out.println(Playing mp3 file. Name: fileName);} else if (audioType.equalsIgnoreCase(vlc) || audioType.equalsIgnoreCase(mp4)) {mediaAdapter new MediaAdapter(audioType);mediaAdapter.play(audioType, fileName);} else {System.out.println(Invalid media. audioType format not supported);}}
}应用场景
适配器模式适用于以下场景
当需要在一个已有系统中引入新的功能或者接口时它与系统的目标接口不兼容但又不能修改原有代码时可以使用适配器模式。例如在一个数据库操作系统中如果想要支持多种类型的数据库源但系统只提供了一个固定类型数据库源的操作接口时可以使用一个数据库源操作适配器来将不同类型数据库源转换成统一类型数据库源。 当需要在多个独立开发的系统或者组件之间进行协作时但由于各自采用了不同的接口或者协议时可以使用适配器模式。例如在一个分布式服务系统中如果想要让不同语言编写的服务之间进行通信和调用但各自采用了不同的通信协议和数据格式时可以使用一个服务通信适配器来将不同协议和数据格式转换成统一协议和数据格式。
优点
适配器模式可以增强程序的可扩展性通过使用适配器可以在不修改原有代码的基础上引入新的功能或者接口。 适配器模式可以提高类的复用性通过使用适配器可以将已有的类或者接口重新组合和封装使其符合新的需求。 适配器模式可以增加类的透明度通过使用适配器客户端只需要关注目标接口而无需了解被适配者的具体实现。 适配器模式可以灵活地切换不同的被适配者通过使用不同的适配器可以动态地选择不同的被适配者来满足不同的场景。
缺点
适配器模式会增加系统的复杂性过多地使用适配器会使系统变得零乱和难以理解。 适配器模式可能会降低系统的性能因为每次调用目标接口时都需要经过适配器的转换。 适配器模式可能会违反开闭原则如果目标接口发生变化则需要修改所有的适配器类。