结构型模式 - 适配器模式(兼容接口)

适配器模式(Adapter Pattern)

简介

作为两个不兼容接口之间的桥梁,结合了2个独立接口的功能。

意图

将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

使用场景

  1. 当系统需要使用现有的类,而类的接口不兼容时(不符合系统需要);
    例子:美国家用电器标准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能够使用的形式。

示例代码

  1. 创建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
posted @ 2021-01-11 23:46  明明1109  阅读(157)  评论(0编辑  收藏  举报