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);
}
}
}