简单的说就是将一个类的接口转换成客户希望的另一个接口。
举例理解:
你买了一个苹果手机,但是家里的数据线都是安卓的,你想用安卓的线充你的苹果手机,那你就需要一个转接头。适配器模式就是适用于这种情况。
适配的本质就是转换,将不满足使用条件的东西通过第三方类进行加工处理成可使用的东西。适配器模式用来解决现有对象与客户端期待接口不一致的问题。
基本角色:
系统需要复用现有类,但是接口又与复用环境要求不一致的情况。
旧系统与新系统的兼容:
可以使新系统能够无缝地与老旧系统进行通信。
第三方组件的集成:
适配器可以将第三方组件的接口转换为符合我们系统需求的接口形式,从而能够顺利地集成到我们的系统中。
多个类库之间的互操作:
适配器模式可以起到桥梁的作用。
举例:例如海康SDK之类的dll文件没有.NET Core版本的,只有Java的支持跨平台,这时候我们需要使用就可以直接引入Java版本的SDK,用适配器生成接口即可。
适配器模式分为两类:类适配器和对象适配器。
下面以苹果手机使用安卓充电线为例
被适配者
- /// <summary>
- /// 被适配者,,安卓线
- /// </summary>
- public class MyAdaptee
- {
- /// <summary>
- /// 你希望使用的方法
- /// </summary>
- public void CD()
- {
- Console.WriteLine("我开始充电");
- }
- }
适配器
- /// <summary>
- /// 适配器---转接头
- /// </summary>
- public class MyAdapter : MyAdaptee, MyTarget
- {
- public void ZH()
- {
- base.CD();//使用充电功能,但是方法由CD变为了ZH
- }
- }
目标角色
- /// <summary>
- /// 目标角色---苹果充电线,这里可以写成抽象类或者接口
- /// </summary>
- public interface MyTarget
- {
- void ZH();
- }
客户端角色(使用者)
- /// <summary>
- /// 使用,客户端角色
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void WTBtn_Click(object sender, EventArgs e)
- {
- //假如你能直接使用安卓线,也就是被适配者
- Console.WriteLine("安卓手机需要充电\n");
- MyAdaptee adaptee = new MyAdaptee();
- adaptee.CD();
- //你买了苹果手机,没法直接用安卓手机冲了,加个转接头
- MyTarget my = new MyAdapter();
- Console.WriteLine("苹果手机需要充电\n");
- my.ZH();
- }

优点:
1、可以在不修改原有代码的基础上来复用现有类,很好地符合 “开闭原则”
2、可以重新定义Adaptee(被适配的类)的部分行为,因为在类适配器模式中,Adapter是Adaptee的子类
3、仅仅引入一个对象,并不需要额外的字段来引用Adaptee(被适配者)实例(这个即是优点也是缺点)。
缺点:
1、用一个具体的Adapter(适配器)类对Adaptee(被适配者)和Target(目标角色)进行匹配,当如果想要匹配一个类以及所有它的子类时,类的适配器模式就不能胜任了。因为类的适配器模式中没有引入Adaptee的实例。
2、采用了 “多继承”的实现方式,带来了不良的高耦合。
被适配者(与类适配器一致)
- /// <summary>
- /// 被适配者,,安卓线
- /// </summary>
- public class MyAdaptee
- {
- /// <summary>
- /// 你希望使用的方法
- /// </summary>
- public void CD()
- {
- Console.WriteLine("我开始充电");
- }
- }
适配器(区别在这)
- /// <summary>
- /// 适配器---转接头
- /// </summary>
- public class MyAdapter : MyTarget
- {
- MyAdaptee adaptee = new MyAdaptee();
- public void ZH()
- {
- adaptee.CD();//使用充电功能,但是方法由CD变为了ZH
- }
- }
目标角色(与类适配器一致)
- /// <summary>
- /// 目标角色---苹果充电线,这里可以写成抽象类或者接口
- /// </summary>
- public interface MyTarget
- {
- void ZH();
- }
客户端角色
- /// <summary>
- /// 使用,客户端角色
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void WTBtn_Click(object sender, EventArgs e)
- {
- //假如你能直接使用安卓线,也就是被适配者
- Console.WriteLine("安卓手机需要充电\n");
- MyAdaptee adaptee = new MyAdaptee();
- adaptee.CD();
- //你买了苹果手机,没法直接用安卓手机冲了,加个转接头
- MyTarget my = new MyAdapter();
- Console.WriteLine("苹果手机需要充电\n");
- my.ZH();
- }

优点:
1、可以在不修改原有代码的基础上来复用现有类,很好地符合 “开闭原则”(这点是两种实现方式都具有的)
2、采用 “对象组合”的方式,更符合松耦合。
缺点:
1、使得重定义Adaptee的行为较困难,这就需要生成Adaptee的子类并且使得Adapter引用这个子类而不是引用Adaptee本身。
总结:
由例子可以看出类适配与对象适配在于一个继承被适配者,一个实例化被适配者。 类适配器采用“多继承”的实现方式,在C#语言中,如果被适配角色是类,Target的实现只能是接口,因为C#语言只支持接口的多继承的特性。在C#语言中类适配器也很难支持适配多个对象的情况,同时也会带来了不良的高耦合和违反类的职责单一的原则,所以一般不推荐使用。对象适配器采用“对象组合”的方式,更符合松耦合精神,对适配的对象也没限制,可以一个,也可以多个,但是,使得重定义Adaptee的行为较困难,这就需要生成Adaptee的子类并且使得Adapter引用这个子类而不是引用Adaptee本身。
END--------------------------------------------------------------------------------------------------------------------------