1. 介绍

适配器模式就是用来做适配,他将不兼容的接口转换为可兼容的接口,让原本由于接口不兼容而不能一起工作的类可以一起工作,适配器模式有两种:类适配器和对象适配器。其中,类适配器使用继承关系来实现,对象适配器使用组合关系来实现。

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

2. 使用场景

  • 封装有缺陷的接口设计

  • 封装多个类的接口设计

  • 替换依赖的外部系统

  • 兼容老版本接口

  • 适配不同格式的数据

3. 代码示例

有一个通用的音效播放接口 IAudioPlayer,你的游戏各个模块(比如主角攻击、UI点击)都通过它来播放音效。

现在 提供了一个新的第三方音效库 ThirdPartySoundSystem,它的使用方式和你当前的接口完全不同。

你不能直接修改第三方库的代码,也不想改你已有的所有调用逻辑,于是你选择用 适配器模式。

结构说明(Adapter 模式)

目标接口(Target):IAudioPlayer

适配者(Adaptee):ThirdPartySoundSystem(第三方库)

适配器(Adapter):ThirdPartySoundAdapter

///


    public class AdapterDesign
    {
        static void Main()
        {
            IAudioPlayer audioPlayer;
         // 这里可以无缝切换 ThirdPartySoundSystem 和 UnityAudioPlayer
            ThirdPartySoundSystem thirdPartySoundSystem = new ThirdPartySoundSystem();
            audioPlayer = new ThirdPartySoundAdapter(thirdPartySoundSystem);
            audioPlayer.playSound("coin");
        }
    }

    //目标接口
    interface IAudioPlayer
    {
        void playSound(string soundName);
    }

    public class UnityAudioPlayer : IAudioPlayer
    {
        public void playSound(string soundName)
        {
            Console.WriteLine($"正在播放{soundName}声音  (系统实现)");
        }
    }

    //第三方库
    public class ThirdPartySoundSystem
    {
        public void PlayClipById(int id)
        {
            Console.WriteLine("Third-party system playing sound with ID: " + id);
        }
    }

    // 适配器:把 ThirdPartySoundSystem 适配成 IAudioPlayer
    class ThirdPartySoundAdapter : IAudioPlayer
    {
        ThirdPartySoundSystem thirdPartySoundSystem;
        // 音效映射
        private Dictionary<string, int> soundNameToIdMap;

       public ThirdPartySoundAdapter(ThirdPartySoundSystem thr)
        {
            this.thirdPartySoundSystem = thr;
            soundNameToIdMap = new Dictionary<string, int>
            {
                {"coin",1},
                {"jump",2},
                {"shooting",3}
            };
        }

        public void playSound(string soundName)
        {
            if (soundNameToIdMap.TryGetValue(soundName, out int id))
            {
                thirdPartySoundSystem.PlayClipById(id);
            }
            else
            {
                Console.WriteLine("声音未找到 " + soundName);
            }
        }
    }