适配器模式
# 分类
结构型模式
# 定义
- 适配器模式(Adapter Pattern) 是作为两个
不兼容接口之间的桥梁
,适配器模式分类适配器模式和对象适配器模式。
# 意图
- 将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
# 应用场景
- 适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况。
- 有动机地修改一个正常运行的系统接口,这是应该考虑使用适配器模式。
应用案例
- 有些国家用110V电压,而我们国家用220V电压,但是我们的电器,比如笔记本电脑是不能什么电压都能使用的。国家不同,电压可能不相同也是事实,于是就用一个电源适配器,只要是电,不管多少伏,都能把电源变成需要的电压,这就是电源适配器的作用。在不能改变电压、电气设备的情况,想使用电气我们只能找个电源适配器来实现。
# 角色与结构图
- Target:
目标接口角色
这是客户所期待的接口,目标接口可以是具体的或者抽象的类,也可以是接口。 - Adaptee:
适配对象角色
需要适配的类。 - Adapter:
适配器角色
继承Target,重写其方法,通过在内部包装一个 Adaptee 对象,把源接口转成目标接口。
下图解释了适配器模式中各角色的作用

# 示例代码
//客户所期待的接口,目标可以是具体的或者抽象的类,也可以是接口。
class Target{
public virtual void Request(){
Console.WriteLine("普通请求");
}
}
//需要适配的类
class Adaptee{
public void SpecificRequest(){
Console.WriteLine("特殊请求");
}
}
//通过在内部包装一个Adaptee对象,把源接口转换成目标接口
class Adapter : Targert{
private Adpatee adpatee = new Adpatee();
public override void Request(){
adaptee.SpecificRequest();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//客户端代码
class Client{
static void Main(String[] args){
Target target = new Adapter();
target.Request();
Console.ReadLine("");
}
}
2
3
4
5
6
7
8
9
# 优点
- 可以让任何两个没有关联的类一起运行。
- 提高了类的复用。
- 增加了类的透明度。
- 灵活性好。
# 缺点
- 过多地使用适配器,会让系统非常凌乱,不易整体进行把握。比如明明看到的是调用接口A,其实内部被适配成了B接口的实现。系统过多的出现无异于异常灾难。因此非必要不使用,尽量重构。
# 小结
适配器模式解决的问题是就是需要的东西就在面前,但却不能使用,而短时间又无法改造它,于是我们就想办法适配它。
在软件开发中,也就是系统的数据和行为都正确,但接口不符时,我们应该考虑用适配器。如果两个类所做的事情相同或者相似,但是具有不同的接口时要使用它。目的就是使控制范围之外的一个原有对象与某个接口匹配。
这个模式一般出现在软件开发后期或者维护期,就是在双方都不太容器修改的时候在使用适配器模式适配,而不是一有不同时就使用。因为早期开发阶段出现这个问题时一般应该考虑通过重构统一接口,这个设计模式有点亡羊补牢的感觉。
在设计早期考虑使用适配器模式一般是在使用第三方开发组件,而这个组件的接口与我们的系统接口不相同,而我们也完全没必要为了迎合它而太懂自己的接口,此时尽管是在开发的设计阶段,也可以考虑用适配器模式来解决接口不同的问题。
主要解决?在软件系统中,常常要将一些现存的对象放到新的环境中,而新环境要求的接口是现对象不能满足的。
何时使用?1 系统需要使用现有的类,而此类的接口不符合系统的需求。2 想要建立一个可以重复使用的类,用于与一些彼此之间没太大关联的一些类,包括一些可能在将来引进的类一起工作,这些源类不一定有一致的接口。3 通过接口转换,将一个类插入另一个类系中。
如何解决?继承或者依赖。
关键代码?适配器继承或者依赖已有的对象,实现想要的目标接口。
注意:适配器模式不是在详细设计时添加的,而是解决正在服役的项目问题。
# 大结
适配,即在不改变原有实现的基础上,将原先不兼容的接口转换为兼容的接口。 动机:在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用。但是新环境要求的接口是这些现存对象所不满足的。 如何应对这种“迁移的变化”?如何既能利用现有对象的良好实现,同时又能满足新的应用环境所要求的接口? 意图:将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 适配器模式主要应用于“希望复用一些现存的类”,但是接口又于复用环境要求不一致的情况,在遗留代码的复用、类库的迁移等方面非常有用。 GoF23定义了两种适配器模式的实现结构:对象适配器和类适配器。但类适配器采用“多继承”的实现方法,带来了不良的高耦合,所以一般不推荐使用。对象适配器采用“对象组合”的方式,更符合松耦合精神。 适配器模式可以实现的非常灵活,不必拘泥于Gof23中定义的两种结构。例如完全可以将适配器模式中的“现存对象”作为新的接口方法参数,来达到适配的目的。 适配器模式本身要求我们尽可能地使用“面向接口的编程”风格,这样才能在后期很方便地适配。
# 一句话概括
将一个类的方法接口转换成客户希望的另一个接口。