引言
适配器模式(Adapter Pattern)是一种结构型设计模式,它可以将两个不兼容的接口之间建立一个桥梁,使它们能够协同工作。这种模式常被用于需要将现有的类与其他类或系统进行集成的情况。
作用
将一个类的接口转换成客户希望的另外一个接口。
适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
解决的问题
-
适配器模式主要解决的问题是在软件系统中,经常需要使用现有类,但这些类的接口与系统要求的接口不兼容的情况。
-
适配器模式通过创建一个适配器类,在其中包装一个已有的类,并将该类的接口转换为系统需要的接口,从而使这两个不兼容的接口能够协同工作。
-
适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。
适配器模式核心
适配器模式的核心是适配器类,它通过继承或依赖已有的类,实现目标接口。适配器类将客户端对目标接口的调用转发给被适配的对象,使其能够完成所需的操作。
优缺点
优点:
- 可以让任何两个没有关联的类一起运行,提高了代码的复用性;
- 增加了类的透明度,客户端只需要和目标接口进行交互,不需要了解具体的适配器类;
- 灵活性好,可以动态地添加或更换适配器,实现不同接口之间的适配。
缺点: - 过多地使用适配器会使系统变得零乱,不易于整体把握;
- JAVA中至多只能继承一个类,所以一个适配器类只能适配一个适配者类,限制了灵活性。
适配器模式的使用
为媒体播放器和更高级的媒体播放器创建接口.
public interface AdvancedVideoPlayer {
public void playMVC(String fileName);
public void playMp4(String fileName);
}
public interface VideoPlayer {
public void play(String audioType, String fileName);
}
创建实现了 AdvancedVideoPlayer 接口的实体类。
public class Mp4Player implements AdvancedVideoPlayer{
@Override
public void playMVC(String fileName) {
//什么也不做
}
@Override
public void playMp4(String fileName) {
System.out.println("Playing mp4 file. Name: "+ fileName);
}
}
public class MVCPlayer implements AdvancedVideoPlayer{
@Override
public void playMVC(String fileName) {
System.out.println("Playing mvc file. Name: "+ fileName);
}
@Override
public void playMp4(String fileName) {
//什么也不做
}
}
创建实现了 VideoPlayer 接口的适配器类。
public class VideoAdapter implements VideoPlayer {
AdvancedVideoPlayer advancedMusicPlayer;
public VideoAdapter(String audioType){
if(audioType.equalsIgnoreCase("mvc") ){
advancedMusicPlayer = new MVCPlayer();
} else if (audioType.equalsIgnoreCase("mp4")){
advancedMusicPlayer = new Mp4Player();
}
}
@Override
public void play(String audioType, String fileName) {
if(audioType.equalsIgnoreCase("mvc")){
advancedMusicPlayer.playMVC(fileName);
}else if(audioType.equalsIgnoreCase("mp4")){
advancedMusicPlayer.playMp4(fileName);
}
}
}
创建实现了 VideoPlayer 接口的实体类。
public class AudioPlayer implements VideoPlayer {
VideoAdapter mediaAdapter;
@Override
public void play(String audioType, String fileName) {
//播放 mp3 音乐文件的内置支持
if(audioType.equalsIgnoreCase("mp3")){
System.out.println("Playing mp3 file. Name: "+ fileName);
}
//mediaAdapter 提供了播放其他文件格式的支持
else if(audioType.equalsIgnoreCase("mvc")
|| audioType.equalsIgnoreCase("mp4")){
mediaAdapter = new VideoAdapter(audioType);
mediaAdapter.play(audioType, fileName);
}
else{
System.out.println("Invalid media. "+
audioType + " format not supported");
}
}
}
使用 AudioPlayer 来播放不同类型的音频格式。
public class AdapterPatternDemo {
public static void main(String[] args) {
AudioPlayer audioPlayer = new AudioPlayer();
audioPlayer.play("mp3", "beyond the horizon.mp3");
audioPlayer.play("mp4", "alone.mp4");
audioPlayer.play("mvc", "far far away.mvc");
audioPlayer.play("avi", "mind me.avi");
}
}
执行程序,输出结果:
com.wrt.creater.Adapter.AdapterPatternDemo
Playing mp3 file. Name: beyond the horizon.mp3
Playing mp4 file. Name: alone.mp4
Playing mvc file. Name: far far away.mvc
Invalid media. avi format not supported
应用场景
- 系统需要使用现有的类,但这些类的接口与系统的要求不一致;
- 希望建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的类一起工作;
- 需要适配一个类到另一个类系中。
总结
适配器模式是一种非常常用且实用的设计模式,通过适配器类的封装,能够很好地实现两个不兼容接口之间的协同工作,提高代码的灵活性和复用性。在实际开发中,我们可以根据具体的需求,灵活运用适配器模式来解决接口不兼容的问题。