适配器模式
1 概述
- 适配器模式(Adapter Pattern)是一种结构型设计模式,它将一个类的接口转换成客户希望的另一个接口,使得原本接口不兼容的类可以一起工作。
- 适配器模式通过在原有接口和目标接口之间创建一个适配器类,实现接口的转换,从而使得客户端可以使用目标接口调用原有接口的方法。
2 优缺点及应用场景
2.1 优点
- 1)提高了类的复用性:通过适配器可以将现有的类与其他接口兼容,使得现有类可以在更多场景下使用。
- 2)提高了类的灵活性:通过使用适配器,可以在不修改现有代码的情况下实现新功能。
- 3)符合开闭原则:通过引入适配器类,可以在不修改现有代码的基础上进行扩展。
2.2 缺点
- 1)增加了代码的复杂性:引入适配器类会增加系统的复杂度,特别是多个适配器类同时存在时。
- 2)可能会导致性能开销:由于适配器模式增加了一层间接调用,可能会导致一定的性能开销。
2.3 应用场景
- 1)接口转换:例如,将 Java JDK 1.1 的 Enumeration 接口转换为 1.2 的 Iterator 接口。
- 2)已有类的接口不符合需求:当我们想使用一个已经存在的类,但它的接口不符合我们的需求时,可以使用适配器模式。
- 3)希望复用一些现有的类,但是这些类的接口又与复用环境要求的接口不一致时。
- 4)构建一个可重用的类库,适配器模式可以帮助我们使类库与其他类库或系统兼容。
3 结构
- 1)目标接口(Target):定义客户需要的接口。
- 2)适配者类(Adaptee):定义一个已经存在的接口,这个接口需要适配。
- 3)适配器类(Adapter):实现目标接口,并通过组合或继承的方式调用适配者类中的方法,从而实现目标接口。
4 实现
4.1 UML 类图

4.2 代码示例
interface MediaPlayer {
public void play(String audioType, String fileName);
}
interface AdvancedMediaPlayer {
public void playVlc(String fileName);
public void playMp4(String fileName);
}
class VlcPlayer implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
System.out.println("Playing vlc file. Name: " + fileName);
}
@Override
public void playMp4(String fileName) {
}
}
class Mp4Player implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
}
@Override
public void playMp4(String fileName) {
System.out.println("Playing mp4 file. Name: " + fileName);
}
}
class MediaAdapter implements MediaPlayer {
AdvancedMediaPlayer advancedMusicPlayer;
public MediaAdapter(String audioType) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMusicPlayer = new VlcPlayer();
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMusicPlayer = new Mp4Player();
}
}
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMusicPlayer.playVlc(fileName);
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMusicPlayer.playMp4(fileName);
}
}
}
class AudioPlayer implements MediaPlayer {
MediaAdapter mediaAdapter;
@Override
public 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");
}
}
}
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("vlc", "far far away.vlc");
audioPlayer.play("avi", "mind me.avi");
}
}
Playing mp3 file. Name: beyond the horizon.mp3
Playing mp4 file. Name: alone.mp4
Playing vlc file. Name: far far away.vlc
Invalid media. avi format not supported
5 总结
- 适配器模式通过在原有接口和目标接口之间创建一个适配器类,实现接口的转换,从而使得原本接口不兼容的类可以一起工作。适配器模式提高了类的复用性和灵活性,符合开闭原则,但也增加了系统的复杂性。适配器模式适用于已有类的接口不符合需求的情况,或希望复用一些现有的类但接口不一致的情况。