适配器模式学习

适配器模式(Adapter)的定义如下:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。适配器模式分为类结构型模式对象结构型模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。
由于类适配器模式通过多重继承对一个接口与另一个接口进行匹配,而C#、VB.NET、Java等语言不支持多重继承(C++支持),也就是一个类只有一个父类,所以这里主要将的是对象适配器。其UML图如下:
在这里插入图片描述
下面以高级音频播放器能播放MP4和vr文件,将其适配为我们系统的播放器接口,并且保留其播放MP4
和vr文件的功能为例子。
所涉及到的角色:

  1. 目标接口(这个接口是我们系统需要的)
  2. 适配者类(这个类是已经存在的,且不好或者无法修改的)
  3. 适配器类(转接器,通过它可以将适配者转换为我们需要的目标接口类型)

目标接口:

/**
 * 播放器
 * @author Linging
 * @version 1.0.0
 * @since 1.0
 */
public interface Player {

    /**
     * 播放
     * @param type 格式
     * @param name 播放的歌曲名称
     */
    void play(String type, String name);

}

适配者类:

/**
 * 高级播放接口,它有两个实现MP4和vr
 * @author Linging
 * @version 1.0.0
 * @since 1.0
 */
public interface AdvancedPlayer {

    /**
     * 播放MP4
     * @param name
     */
    void playMP4(String name);

    /**
     * 播放VR
     * @param name
     */
    void playVR(String name);
}
/**
 * MP4播放器
 * @author Linging
 * @version 1.0.0
 * @since 1.0
 */
public class Mp4Player implements AdvancedPlayer{
    @Override
    public void playMP4(String name) {
        System.out.println("play mp4 file: " + name);
    }

    @Override
    public void playVR(String name) {

    }
}
/**
 * Vr播放器
 * @author Linging
 * @version 1.0.0
 * @since 1.0
 */
public class VrPlayer implements AdvancedPlayer{
    @Override
    public void playMP4(String name) {

    }

    @Override
    public void playVR(String name) {
        System.out.println("play vr file: " + name);
    }
}

适配器类:

/**
 * 音频适配器 使最原始的player能适配MP4和vr格式的音频
 * @author Linging
 * @version 1.0.0
 * @since 1.0
 */
public class AudioAdapter implements Player{

    AdvancedPlayer advancedPlayer;

    public AudioAdapter(String type) {
        if(type.equalsIgnoreCase("mp4")){
            advancedPlayer = new Mp4Player();
        }else if(type.equalsIgnoreCase("vr")){
            advancedPlayer = new VrPlayer();
        }
    }

    @Override
    public void play(String type, String name) {
        if(type.equalsIgnoreCase("mp4")){
            advancedPlayer.playMP4(name);
        }else if(type.equalsIgnoreCase("vr")){
            advancedPlayer.playVR(name);
        }
    }
}

目标接口的实现:

/**
 * 目前有一个音频播放器,内置播放MP3格式的音频
 * 但是现在想要播放其他格式的音频,MP4和VR视频,所以需要进行适配
 * @author Linging
 * @version 1.0.0
 * @since 1.0
 */
public class AudioPlayer implements Player{

    AudioAdapter adapter;

    @Override
    public void play(String type, String name) {
        if(type.equalsIgnoreCase("mp3")){
            System.out.println("play mp3 file: " + name);
        }
        //适配的格式
        else if(type.equalsIgnoreCase("mp4") || type.equalsIgnoreCase("vr")){
            adapter = new AudioAdapter(type);
            adapter.play(type, name);
        }else {
            System.out.println("暂不支持播放:" + type + " 类型的文件");
        }
    }
}

测试:

public class Main {

    public static void main(String[] args) {
        // AudioPlayer内置默认播放MP3
        // 适配之后可以播放mp4和vr
        // 适配:AdvancedPlayer接口 --> Player接口
        AudioPlayer player = new AudioPlayer();

        player.play("mp3", "再给我两分钟");
        player.play("mp4", "hahah.mp4");
        player.play("vr", "嘿嘿.vr");
    }
}

适配器模式总结:
优点:

  • 客户端通过适配器可以透明地调用目标接口。
  • 复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类。
  • 将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题。
  • 在很多业务场景中符合开闭原则。

缺点:

  • 适配器编写过程需要结合业务场景全面考虑,可能会增加系统的复杂性。
  • 增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值