结构型——适配器模式

推荐文档:

https://www.cnblogs.com/zhili/p/DesignPatternSummery.html

https://www.runoob.com/design-pattern/design-pattern-tutorial.html

什么是适配器模式?#

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。

举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

相关介绍#

意图:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

主要解决:主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。

何时使用: 1、系统需要使用现有的类,而此类的接口不符合系统的需要。 2、想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作,这些源类不一定有一致的接口。 3、通过接口转换,将一个类插入另一个类系中。(比如老虎和飞禽,现在多了一个飞虎,在不增加实体的需求下,增加一个适配器,在里面包容一个虎对象,实现飞的接口。)

如何解决:继承或依赖(推荐)。

关键代码:适配器继承或依赖已有的对象,实现想要的目标接口。

应用实例: 1、美国电器 110V,中国 220V,就要有一个适配器将 110V 转化为 220V。 2、JAVA JDK 1.1 提供了 Enumeration 接口,而在 1.2 中提供了 Iterator 接口,想要使用 1.2 的 JDK,则要将以前系统的 Enumeration 接口转化为 Iterator 接口,这时就需要适配器模式。 3、在 LINUX 上运行 WINDOWS 程序。 4、JAVA 中的 jdbc。

优点: 1、可以让任何两个没有关联的类一起运行。 2、提高了类的复用。 3、增加了类的透明度。 4、灵活性好。

缺点: 1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。 2.由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。

使用场景:有动机地修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。

注意事项:适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。

相关实现#

我们有一个 MediaPlayer 接口和一个实现了 MediaPlayer 接口的实体类 AudioPlayer。默认情况下,AudioPlayer 可以播放 mp3 格式的音频文件。

我们还有另一个接口 AdvancedMediaPlayer 和实现了 AdvancedMediaPlayer 接口的实体类。该类可以播放 vlc 和 mp4 格式的文件。

我们想要让 AudioPlayer 播放其他格式的音频文件。为了实现这个功能,我们需要创建一个实现了 MediaPlayer 接口的适配器类 MediaAdapter,并使用 AdvancedMediaPlayer 对象来播放所需的格式。

AudioPlayer 使用适配器类 MediaAdapter 传递所需的音频类型,不需要知道能播放所需格式音频的实际类。AdapterPatternDemo 类使用 AudioPlayer 类来播放各种格式。

 

复制代码
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 
  7 namespace Biao.DesignPatterns.StructuralPatterns
  8 {
  9     /// <summary>
 10     /// 创建2个 为媒体播放器和更高级的媒体播放器 的接口
 11     /// </summary>
 12     public interface MediaPlayer
 13     {
 14         public void Play(string audioType, string fileName);
 15     }
 16 
 17     public interface AdvancedMediaPlayer
 18     {
 19         public void PlayVlc(string fileName);
 20         public void PlayMp4(string fileName);
 21     }
 22 
 23     /// <summary>
 24     /// 创建2个实现了AdvancedMediaPlayer接口的实体类
 25     /// </summary>
 26     public class VlcPlayer : AdvancedMediaPlayer
 27     {
 28         public void PlayVlc(string fileName)
 29         {
 30             Console.WriteLine("Playing vlc file. Name:" + fileName);
 31         }
 32 
 33         public void PlayMp4(string fileName)
 34         {
 35             // 什么也不做
 36         }
 37     }
 38 
 39     public class MP4Player : AdvancedMediaPlayer
 40     {
 41         public void PlayMp4(string fileName)
 42         {
 43             Console.WriteLine("Playing mp4 file. Name:" + fileName);
 44         }
 45 
 46         public void PlayVlc(string fileName)
 47         {
 48             // 什么也不做
 49         }
 50     }
 51 
 52     /// <summary>
 53     /// 创建实现了MediaPlayer接口的适配器类
 54     /// </summary>
 55     public class MediaAdapter : MediaPlayer
 56     {
 57         AdvancedMediaPlayer advancedMediaPlayer;
 58 
 59         public MediaAdapter(string audioType)
 60         {
 61             if (audioType.Equals("vlc"))
 62             {
 63                 advancedMediaPlayer = new VlcPlayer();
 64             }
 65             else if (audioType.Equals("mp4"))
 66             {
 67                 advancedMediaPlayer = new MP4Player();
 68             }
 69         }
 70 
 71         public void Play(string audioType, string fileName)
 72         {
 73             if (audioType.Equals("vlc"))
 74             {
 75                 advancedMediaPlayer.PlayVlc(fileName);
 76             }
 77             else if (audioType.Equals("mp4"))
 78             {
 79                 advancedMediaPlayer.PlayMp4(fileName);
 80             }
 81         }
 82     }
 83 
 84     public class AudioPlayer : MediaPlayer
 85     {
 86         MediaAdapter mediaAdapter;
 87 
 88         public void Play(string audioType, string fileName)
 89         {
 90             if (audioType.Equals("mp3"))
 91             {
 92                 Console.WriteLine("Playing mp3 file. Name:" + fileName);
 93             }
 94             else if (audioType.Equals("vlc") || audioType.Equals("mp4"))
 95             {
 96                 mediaAdapter = new MediaAdapter(audioType);
 97                 mediaAdapter.Play(audioType, fileName);
 98             }
 99             else
100             {
101                 Console.WriteLine($"Invalid media. {audioType} format not supported");
102             }
103         }
104     }
105 }
106  
107 
108 static void TestAdapterPattern()
109 {
110     Console.WriteLine("---------------测试适配器模式---------------");
111     AudioPlayer audioPlayer = new AudioPlayer();
112     audioPlayer.Play("mp3", "只因你太美.mp3");
113     audioPlayer.Play("mp4", "铁山靠.mp4");
114     audioPlayer.Play("vlc", "泥食不食油饼.vlc");
115     audioPlayer.Play("avi", "荔枝.avi");
116 }
复制代码

 


posted @   不爱菠萝的菠萝君  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
主题色彩
点击右上角即可分享
微信分享提示