服务端

一起来学习设计模式:适配器模式

2018-10-21  本文已影响14人  __y

前言:
学习设计模式是为了更好地用面向对象的思维去设计,去编写我们的代码,也为了我们去看源码,学习别人优秀的设计做好准备;写的一些东西都是自己的一些笔记,大家都可以去网上搜相关的博客来学习~欢迎各位交流

1.适配器概念

适配器模式(Adapter Pattern)是两个八竿子打不着的接口之间的桥梁。它结合了两个接口的独立功能。这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。比如我们自己买的显示屏,想连到电脑上有HDMI这种转换线等等。这里的转换线就是一个适配器,让我们的电脑和显示器可以连在一起。

2.实现

image.png

分析:
从上面的图我们可以分析:假设现在我们有两个接口,分别是AdancedMediaPlayer和MediaPlayer,他们分别都有自己的实现类,现在我们要通过一个适配器把这些功能都统一起来管理
按照上面的UML图
我们可以用代码做如下实现:

step1:

创建一个AdancedMediaPlayer 接口和他的实现类

public interface AdancedMediaPlayer {
     void playVlc(String fileName);
     void playMp4(String fileName);
}

public class MP4Player implements AdancedMediaPlayer {
    @Override
    public void playVlc(String fileName) {
        //啥也不做
    }

    @Override
    public void playMp4(String fileName) {
        System.out.println("Playing mp4 file. Name: "+ fileName);

    }
}

step2:

创建适配器,创建一个MediaPlayer接口,并利用组合的方式,将AdancedMediaPlayer 依赖进来

public interface MediaPlayer {
    void play(String audioType, String fileName);
}
public class MediaAdapter implements MediaPlayer {
    AdancedMediaPlayer advancedMusicPlayer;

    public MediaAdapter(String  audioType) {
        //放进来适配
        if(audioType.equalsIgnoreCase("vlc") ){
            advancedMusicPlayer = new VclPlayer();
        } 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);
        }
    }
}

这里是比较重点的,因为就是这里利用了适配器模式
我们可以看到巧妙地利用构造方法和组合的方式,就可以把AdancedMediaPlayer 组合进来,从而可以在后面的代码中复用这些功能

step3:

创建MediaPlayer的实现类,在保证自己功能实现的情况下,引入适配器,从而可以调用适配器中的功能

public class AudioPlayer implements MediaPlayer{
    MediaAdapter mediaAdapter;
    @Override
    public void play(String audioType, String fileName) {
        //播放MP3,本来接口存在的方法
        if(audioType.equalsIgnoreCase("mp3")) {
            System.out.println("Playing mp3 file. Name: "+ fileName);
        }else if(audioType.equalsIgnoreCase("vlc")
                || audioType.equalsIgnoreCase("mp4")) {
            //mediaAdapter 提供了播放其他文件格式的支持,这里利用适配器使用其他功能
            mediaAdapter = new MediaAdapter(audioType);
            mediaAdapter.play(audioType, fileName);
        } else{
            System.out.println("Invalid media. "+
                    audioType + " format not supported");
        }


    }
}

step4:

具体测试类:

public class AdapterPatternDemo {
    public static void main(String[] args) {
        AudioPlayer audioPlayer = new AudioPlayer();
        audioPlayer.play("mp3", "1.mp3");
        audioPlayer.play("mp4", "2.mp4");
        audioPlayer.play("vlc", "3.vlc");
        audioPlayer.play("avi", "4.avi");
    }
}

结果:

image.png
教程入口:
www.coder520.com 码码在线
http://www.runoob.com/design-pattern/adapter-pattern.html 菜鸟教程

3.总结:

其实从上面的展示来看,就是将两个相对独立的功能,放在一块实现,当我们具体调用的时候便于我们一定的扩展,想想如果我们没用适配器模式的话,具体的程序入口代码块那就要每次都要new 一个对应的对象出来,下次如果这个对象不用了,我们又得找到这一段代码把它注释掉或者删掉;很麻烦,代码量上去的话,找这一段代码的时间,我可能都已经写下一个功能。因此,总的来说适配器设计模式还是有利于我们的。但是,还是要提一句,用的不要泛滥,不然明明是调用A接口功能的,又有B功能的存在,如果功能点越来越多,你还往里面放的话,那代码可阅读性和维护都很麻烦~
引用一句比较流行的话:可以用但是没必要~

上一篇下一篇

猜你喜欢

热点阅读