适配器模式(Adapter Pattern)是一种结构型设计模式,它允许不兼容的接口一起工作。适配器模式主要有两种形式:类适配器和对象适配器。这两种形式都旨在解决现有类接口与所需接口不匹配的问题。
### 主要组成部分
1. **Target(目标接口)**:定义客户端所期望的接口。
2. **Adaptee(被适配的类)**:已经存在的、具有某些功能但不符合目标接口的对象。
3. **Adapter(适配器)**:通过继承或组合的方式,将被适配者的接口转换为目标接口,从而使它们能够协同工作。
### 类适配器 vs 对象适配器
- **类适配器**:通过继承实现。适配器类继承自被适配者,并实现目标接口。
- **对象适配器**:通过组合实现。适配器类持有一个被适配者的实例,并实现目标接口。
### 示例代码
假设我们有一个现有的音频播放器接口,但它只能播放MP3格式的文件。现在我们需要扩展它的功能,使其能够播放VLC和MP4格式的文件。
#### 目标接口
```java
public interface MediaPlayer {
void play(String audioType, String fileName);
}
```
#### 被适配的类
```java
public class AudioPlayer implements MediaPlayer {
@Override
public void play(String audioType, String fileName) {
if ("mp3".equalsIgnoreCase(audioType)) {
System.out.println("Playing mp3 file. Name: " + fileName);
} else {
System.out.println("Invalid media. " + audioType + " format not supported.");
}
}
}
```
#### 适配器接口
```java
public interface AdvancedMediaPlayer {
void playVlc(String fileName);
void playMp4(String fileName);
}
```
#### 被适配的具体实现
```java
public class VlcPlayer implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
System.out.println("Playing vlc file. Name: " + fileName);
}
@Override
public void playMp4(String fileName) {
// 不支持
}
}
public class Mp4Player implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
// 不支持
}
@Override
public void playMp4(String fileName) {
System.out.println("Playing mp4 file. Name: " + fileName);
}
}
```
#### 适配器类
```java
public class MediaAdapter implements MediaPlayer {
private 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);
}
}
}
```
#### 客户端
```java
public class AudioPlayerDemo {
public static void main(String[] args) {
AudioPlayer audioPlayer = new AudioPlayer();
audioPlayer.play("mp3", "beyond.mp3");
audioPlayer.play("mp4", "alone.mp4");
audioPlayer.play("vlc", "far far away.vlc");
audioPlayer.play("avi", "mind me.avi");
}
}
```
### 运行结果
```
Playing mp3 file. Name: beyond.mp3
Playing mp4 file. Name: alone.mp4
Playing vlc file. Name: far far away.vlc
Invalid media. avi format not supported.
```
### 总结
适配器模式通过引入一个新的适配器类,将一个接口转换成另一个接口,从而使原本不兼容的类能够一起工作。这种模式在软件开发中非常常见,尤其是在需要集成第三方库或旧有系统时。适配器模式可以通过类适配器或对象适配器来实现,选择哪种方式取决于具体的需求和设计考虑。