结构型模式 - 适配器模式(兼容接口)
适配器模式(Adapter Pattern)
简介
作为两个不兼容接口之间的桥梁,结合了2个独立接口的功能。
意图
将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
使用场景
- 当系统需要使用现有的类,而类的接口不兼容时(不符合系统需要);
例子:美国家用电器标准110V,中国220V,要在美国使用中国电器,就需要一个装置将110V转换成220V,这个装置就叫适配器。
特点
-
优点
可以让2个原本没有关联的类一起运行;提供类的复用性,而不用修改原来的类; -
缺点
过多使用适配器,容易造成系统混乱,不易整体把握。不是很有必要,不建议使用,更好的方式是直接重构。
示例及UML类图
原有AudioPlayer实现了接口MediaPlayer,支持播放mp3音乐;原有接口AdvancedMediaPlayer接口及实现类VlcPlayer和Mp4Player,分别支持播放VLC格式和mp4格式文件。不过,AudioPlayer却无法直接通过play来播放vlc和mp4格式,因为接口不兼容。AudioPlayer通过play()方法播放,而VlcPlayer和Mp4Player具有playVlc()和playMp4()播放。
现在通过增加适配器MediaAdapter,将AdvancedMediaPlayer接口转换为AudioPlayer能够使用的形式。
示例代码
- 创建MediaPlayer和AdvancedMediaPlayer接口
// MediaPlayer.javapublic interface MediaPlayer { public void player();}
// AdvancedMediaPlayer.java
public interface AdvancedMediaPlayer {
public void playVlc();
public void playMp4();
}
2.创建AdvancedMediaPlayer实体类
// VlcPlayer.java
public class VlcPlayer implements AdvaancedMediaPlayer {
@Override
public void playVlc() {
System.out.prinln("VlcPlayer::playVlc() method");
}
@Override
public void PlayMp4() { }
}
// Mp4Player.java
public class Mp4Player implements AdvaancedMediaPlayer {
@Override
public void playVlc() { }
@Override
public void playMp4() {
System.out.prinln("Mp4Player::playVlc() method");
}
}
3.创建适配器类MediaAdapter
// MediaAdapter.java
public class MediaAdapter implements MediaPlayer {
AdvancedMediaPlayer player;
public MediaPlayer(String audioType) {
if(audioType.equalsIgnoreCase("vlc")) {
player = new VlcPlayer();
}
else if(audioType.equalsIgnoreCase("mp4")) {
player = new Mp4Player();
}
}
public void play(String audioType, String fileName) {
if(audioType.equalsIgnoreCase("vlc")) {
player.playVlc();
}
else if(audioType.equalsIgnoreCase("mp4")) {
player.playMp4();
}
}
}
4.创建MediaPlayer实体类AudioPlayer
// AudioPlayer.java
public class AudioPlayer implements MediaPlayer {
MediaAdapter adapter;
@Override
public void play(String type, String fileName) {
if(type.equalsIgnoreCase("mp3")) {
System.out.println("Playing mp3 file: " + fileName);
}
else if(type.equalsIgnoreCase("vlc") || type.equalsIgnoreCase("mp4")) {
adapter = new MediaAdapter(type);
adapter.play(type, fileName);
}
else {
System.out.println("invalid media type: " + type);
}
}
}
5.AdapterPatternDemo使用MediaPlayer及适配器MediaAdapter
// AdapterPatternDemo.java
public class AdpaterPatternDemo {
public static void main(String[] args) {
AudioPlayer audioPlayer = new AudioPlayer();
audioPlayer.play("mp3", "spring.mp3");
audioPlayer.play("mp4", "alone.mp4");
audioPlayer.play("vlc", "far far away.vlc");
audioPlayer.play("avi", "mind me.avi");
}
}
6.运行结果
Playing mp3 file: spring.mp3
Mp4Player::playMp4() play: alone.mp4
VlcPlayer::playVlc() play: far far away.vlc
invalid media type: avi