欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

设计模式系列 - 适配器模式

程序员文章站 2022-04-05 11:26:05
见名知其意,适配器可用于对多个不兼容接口提供适配桥梁 介绍 适配器模式属于结构型模式。在现实世界中,这个模式适用的较为广泛,比如 DIY 一些电子产品,主要元器件提供的是标准接口,那么无论我们购买什么品牌的元器件,最终都能组装起来正常运行。 类图描述 由上图可知,我们通过定义 IAdvancedMe ......

见名知其意,适配器可用于对多个不兼容接口提供适配桥梁

介绍

适配器模式属于结构型模式。在现实世界中,这个模式适用的较为广泛,比如 diy 一些电子产品,主要元器件提供的是标准接口,那么无论我们购买什么品牌的元器件,最终都能组装起来正常运行。

类图描述

设计模式系列 - 适配器模式

由上图可知,我们通过定义 iadvancedmediaplayer 接口来约束 mp4playervlcplayer 的播放行为。然后定义一个 适配器 mediaadapter 来管理创建具体的某种类型的播放。audioplayer 为已支持的播放类型,然后在其内部通过调用适配器达到支持扩展类型的播放功能。

代码实现

1、定义扩展接口和受支持的类型

public interface iadvancedmediaplayer
{
    void playvlc(string filenmae);
    void playmp4(string filenmae);
}

public enum audiotype
{
    mp3,
    vlc,
    mp4,
    unknown
}

2、定义具体类型的播放类

public class mp4player:iadvancedmediaplayer
{
    public void playvlc(string filenmae)
    {
    }

    public void playmp4(string filenmae)
    {
        console.writeline($"playing mp4 file.name:{filenmae}");
    }
}

public class vlcplayer:iadvancedmediaplayer
{
    public void playvlc(string filenmae)
    {
        console.writeline($"playing vlc file.name:{filenmae}");
    }

    public void playmp4(string filenmae)
    {
    }
}

3、定义适配器

public class mediaadapter:imediaplayer
{
    private iadvancedmediaplayer advancedmediaplayer;

    public mediaadapter(audiotype audiotype)
    {
        switch (audiotype)
        {
            case audiotype.vlc:
                advancedmediaplayer = new vlcplayer();
                break;
            case audiotype.mp4:
                advancedmediaplayer = new mp4player();
                break;
            default:
                throw new argumentoutofrangeexception(nameof(audiotype), audiotype, null);
        }
    }

    public void play(audiotype audiotype, string filename)
    {
        switch (audiotype)
        {
            case audiotype.vlc:
                advancedmediaplayer.playvlc(filename);
                break;
            case audiotype.mp4:
                advancedmediaplayer.playmp4(filename);
                break;
            default:
                throw new argumentoutofrangeexception(nameof(audiotype), audiotype, null);
        }
    }
}

4、使用适配器

public  interface imediaplayer
{
    void play(audiotype audiotype, string filename);
}

public class audioplayer:imediaplayer
{
    private imediaplayer mediaadapter;
    public void play(audiotype audiotype, string filename)
    {
        switch (audiotype)
        {
            case audiotype.mp3:
                console.writeline($"playing mp3 file. name:{filename}");
                break;
            case audiotype.vlc:
            case audiotype.mp4:
                mediaadapter = new mediaadapter(audiotype);
                mediaadapter.play(audiotype, filename);
                break;
            default:
                console.writeline($"invalid media.{audiotype} format not supported");
                break;
        }
    }
}

5、上层调用

class program
{
    static void main(string[] args)
    {
        imediaplayer audioplayer = new audioplayer();
        audioplayer.play(audiotype.mp3, "beyond the horizon.mp3");
        audioplayer.play(audiotype.mp4, "alone.mp4");
        audioplayer.play(audiotype.vlc, "far far away.vlc");
        audioplayer.play(audiotype.unknown, "mind me.avi");

        console.readkey();
    }
}

总结

适配器的使用一般是在已有的业务逻辑上进行扩展而来的,可以将任何没有关联的类联系起来,提高了代码的复用。但是在一个系统要从全局出发,不能过多的使用,否则会使系统非常混乱。