适配器模式的实例应用
2012-08-20 17:14 AceYue 阅读(1411) 评论(0) 编辑 收藏 举报适配器模式
Adapter(别名Wrapper)模式:将一个类的接口,转换成客户期望的另一个类的接口。适配器让原本接口不兼容的类可以合作无间。
要点:
1. 适配器模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况”,在遗留代码复用、类库迁移等方面非常有用。
2. 适配器模式有对象适配器和类适配器两种形式的实现结构,但是类适配器采用“多继承”的实现方式,带来了不良的高耦合,所以一般不推荐使用。对象适配器采用“对象组合”的方式,更符合松耦合精神。
适配器模式的优点
- 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,而无须修改原有代码。
- 增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性。
- 灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”。
类适配器模式的缺点如下:
对于Java、C#等不支持多重继承的语言,一次最多只能适配一个适配者类,而且目标抽象类只能为抽象类,不能为具体类,其使用有一定的局限性,不能将一个适配者类和它的子类都适配到目标接口。
类适配器模式还具有如下优点:
由于适配器类是适配者类的子类,因此可以在适配器类中置换一些适配者的方法,使得适配器的灵活性更强.
对象适配器模式还具有如下优点:
一个对象适配器可以把多个不同的适配者适配到同一个目标,也就是说,同一个适配器可以把适配者类和它的子类都适配到目标接口。
对象适配器模式的缺点如下:
与类适配器模式相比,要想置换适配者类的方法就不容易。如果一定要置换掉适配者类的一个或多个方法,就只好先做一个适配者类的子类,将适配者类的方法置换掉,然后再把适配者类的子类当做真正的适配者进行适配,实现过程较为复杂
模式适用环境
系统需要使用现有的类,而这些类的接口不符合系统的需要。
想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
两个类所做到事情相同或者相似,但是具有不同的接口的时候,和客户要求不符合的时候。
旧的系统开发的类已经实现了一些功能,但是客户端却只能以另外接口的形式访问,但是我不希望手动更改原有的类;
使用第三方组件,组件接口定义和自己定义的不同,不希望修改自己定义的接口,但是要使用第三方组件接口的功能。
用例分析
一位用户拿着业界标准开关(一个标准的StandardSwitcher,它依赖IStandardSwitchable接口才能工作,然而目前我们的灯并不支持这个接口)出现在我面前,叫嚣着他的“标准开关”应该能打开我们的灯。好吧,这个需求是合理的,的确应该支持。
两个方案
现在有两个选择。
-
让我们的灯直接支持标准开关。也就是让灯实现IStandardSwitchable接口。
-
好处:成本低,实现方式优雅。
-
坏处:相当于放弃了已经买了我们的灯,又想用标准开关的用户。
-
-
不改变现在的灯,让标准开关能打开我们的灯。标准接口我们改不了,灯也不能改。好在计算机界有句话,叫“加一层可以解决一切问题”。这让我想到了买外国电器附赠的那个电源接口转换器。现在,我们的灯需要个类似的玩意儿。
-
好处:支持所有的灯。
-
坏处:这东西都是要附赠的,会降低我们的利润。
-
第一个方案很简单,就是让Light多实现个接口就OK了。图就不给了。
现在分析第二个方案,标准接口依赖IStandardSwitchable接口,那我们必须有一个类来实现它,并完成所需要的功能——操作灯。咱也是学过设计模式的人,这个问题很明显可以用Adapter模式来解释。

1 public interface IStandardSwitchable 2 { 3 void TurnOn(); 4 void TurnOff(); 5 } 6 7 public class SwitcherAdapter : IStandardSwitchable 8 { 9 public Light Switchee { get; set; } 10 11 public void TurnOn() 12 { 13 Switchee.TurnOn(); 14 } 15 16 public void TurnOff() 17 { 18 Switchee.TurnOff(); 19 } 20 }
目前的需求,我们有灯,有收音机,如果用户说要用标准开关开收音机,难道还要实现一个RadioAdapter不成?
需求是要“通过加一层让灯支持标准开关”,但是并不是说这一层就要使用灯,为了让这个Adapter更加通用,应该让Adapter依赖ISwitchable接口。像下面这个样子。
本文出处:http://www.cnblogs.com/aces/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
请关注我的个人博客:www.afire.com.cn
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述