美文网首页
彻底搞懂适配器模式

彻底搞懂适配器模式

作者: Mr_Zander | 来源:发表于2020-06-02 15:43 被阅读0次

    适配器模式可以看作一种“补偿模式”,用来补救设计上的缺陷。应用这种模式算是“无奈之举”。如果在设计初期,我们就能协调规避接口不兼容的问题,那这种模式就没有应用的机会了。

    适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。

    Talk is cheap, show me the code。

    假设原本系统中有一个音频播放接口 IMP3Player 和它的实现类 MP3Player, 用来播放MP3格式的文件,如下:

    interface IMP3Player {
        func playMP3();
    }
    
    class MP3Player implements IMP3Player {
        func playMP3() {
            print "play mp3";
        }
    }
    

    Mac电脑支持MP3播放:

    interface IMacComputer {
        func playMP3(player: IMP3Player);
    }
    
    class MacComputer implements IMacComputer {
        func playMP3(player: IMP3Player) {
            player.playMP3();   
        }
    }
    

    模拟Mac播放MP3功能:

    class ComputerPlayAudioDemo {
        func main() {
            IMP3Player player = new MP3Player();
            IMacComputer computer = new MacComputer();
            computer.playMP3(player);
        }
    }
    

    同时,ThinkPad支持播放VLC格式的音频:

    interface IVLCPlayer {
        func playVLC();
    }
    
    class VLCPlayer implements IVLCPlayer {
        func playVLC() {
            print "play VLC";
        }
    }
    
    interface IThinkPadComputer {
        func playVLC(player: IVLCPlayer);
    }
    
    class ThinkPadComputer implements IThinkPadComputer {
        func playAudio(player: IVLCPlayer) {
            player.playVLC();   
        }
    }
    
    class ComputerPlayAudioDemo {
        func main() {
            IVLCPlayer player = new VLCPlayer();
            IThinkPadComputer computer = new ThinkPadComputer();
            computer.playVLC(player);
        }
    }
    

    原本双方相安无事,突然需求改动: 需要Mac支持VLC格式的文件。这时可能会在 Computer 中增加一个payer,就是这样:

    interface IMacComputer {
        func playMP3(player: IMP3Player);
        func playVLC(player: IVLCPlayer);
    }
    
    class MacComputer implements IMacComputer {
        func playMP3(player: IMP3Player) {
            player.playMP3();   
        }
    
        func playVLC(player: IVLCPlayer) {
            palyer.playVLC();
        }
    }
    

    这样确实可以解决问题,但是如果你只是播放器厂家呢?而且,给Mac增加一个VLC的播放器就要占用本就捉襟见肘的空间。

    所以最优、最实惠的解决方案还是让播放器适配VLC的功能,这也是适配器模式存在的意义——作为两个不兼容的接口之间的桥梁,补救设计上的缺陷。

    MP3播放器适配VLC:

    class MP3PlayerAdapterVLC implements IMP3Player {
        var vlcPlayer: IVLCPlayer;
        func init(vlcPlayer: IVLCPlayer) {
            self.vlcPlayer = vlcPlayer;
        }
    
        func playMP3() {
            self.vlcPlayer.playVLC();
        }
    }
    

    可以播放VLC的Mac Computer:

    class ComputerPlayAudioDemo {
        func main() {
            IMP3Player player = new MP3Player();
            IMacComputer computer = new MacComputer();
            computer.playMP3(player);
    
            IVLCPlayer vlcPlayer = new VLCPlayer();
            MP3PlayerAdapterVLC adapter = new MP3PlayerAdapterVLC(vlcPlayer);
            computer.playMP3(adapter);
        }
    }
    

    本文到此结束,感谢阅读。

    欢迎关注微信公众号查看更多高质量文章:爱编程的大头

    相关文章

      网友评论

          本文标题:彻底搞懂适配器模式

          本文链接:https://www.haomeiwen.com/subject/lkwuzhtx.html