一、定义

适配器模式把一个类的接口,变换成客户端所期待的另一种接口,使原本因接口不匹配的两个类能够在一起工作。

二、结构

角色

  • Client:用户类,使用新接口Target来完成某些特定的需求。
  • Target:新的接口类,开放特定接口request来完成某些特定操作,与Client协作。
  • Adaptee:原有的类,即需要适配的类或适配者类。
  • Adapter:适配器类,将Adaptee中的接口封装成Target中的新接口,来满足新的需求。

协作

  • Client调用Adapter实例的操作,Adapter使用Adaptee来完成这些被调用的操作。

:类图中表示的是适配器模式两种类图中的对象适配器类图(采用继承实现),另外一种类适配器通过多重继承两个类或实现两个接口来实现(采用对象组合方式实现)。

三、实现

对象适配器

namespace DesignPatterns.Adapter
{
class Program
{
static void Main(string[] args)
{
//使用特殊功能类,即适配类,
// 需要先创建一个被适配类的对象作为参数
PowerAdapter adapter = new PowerAdapter(new RussiaSocket());
adapter.Charge();
}
} /// <summary>
/// 俄罗斯插座
/// PS: 已存在的、具有特殊功能、但不符合我们既有的标准接口的类
/// </summary>
public class RussiaSocket
{
//双脚圆形充电
public void SpecificCharge()
{
Console.WriteLine("充电中...");
}
} /// <summary>
/// 自带的充电插头 - 双脚扁头
/// PS: 目标接口,或称为标准接口
/// </summary>
public interface ICharger
{
void Charge();
} /// <summary>
/// 电源适配器
/// PS: 适配器类,直接关联被适配类,同时实现标准接口
/// </summary>
public class PowerAdapter : ICharger
{
// 直接关联被适配类
private readonly RussiaSocket _russiaSocket;
// 可以通过构造函数传入具体需要适配的被适配类对象
public PowerAdapter(RussiaSocket russiaSocket)
{
_russiaSocket = russiaSocket;
} public void Charge()
{
// 这里是使用委托的方式完成特殊功能
Console.WriteLine("我是适配类:双脚扁头充电->可以在->双脚圆形插孔充电.");
_russiaSocket.SpecificCharge();
}
} }

四、适用场景

   1、 重复使用现有的类,而此类的接口不符合系统的需要。在遗留代码复用、类库迁移等方面非常有用。

  2、 想要建立一个可以重用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。

  3、 使用第三方组件或中间件,组件接口定义和自己定义的不同,不希望修改自己的接口,但是要使用第三方组件接口的功能,避免重复造轮子。

五、优缺点

优点:

1、将目标类和适配者类解耦

2、增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性

3、灵活性和扩展性都非常好,符合开闭原则

  类适配器还有的优点:

    由于适配器类是适配者类的子类,因此可以再适配器类中置换一些适配者的方法,使得适配器的灵活性更强。

  类适配器的缺点:

    对于Java、C#等不支持多重继承的语言,一次最多只能适配一个适配者类,而且目标抽象类只能为接口,不能为类,其使用有一定的局限性,不能将一个适配者类和他的子类同时适配到目标接口。

  对象适配器还有的优点:

    把多个不同的适配者适配到同一个目标,也就是说,同一个适配器可以把适配者类和他的子类都适配到目标接口。

  对象适配器的缺点:

    与类适配器模式相比,要想置换适配者类的方法就不容易。

欢迎阅读本系列文章:Head First设计模式之目录

Head First设计模式之适配器模式的更多相关文章

  1. 每天一个设计模式-3 适配器模式(Adapteer)

    每天一个设计模式-3 适配器模式(Adapteer) 1.现实中的情况 旧式电脑的硬盘是串口的,直接与硬盘连接,新硬盘是并口的,显然新硬盘不能直接连在电脑上,于是就有了转接线.好了,今天的学习主题出来 ...

  2. Head First 设计模式之适配器模式与外观模式

    Head First设计模式之适配器模式与外观模式 前言: 之前讲过装饰者模式,将对象包装起来并赋予新的职责,这一章我们也会将对象进行包装,只不过是让它们看起来不像自己而像是别的东西.这样就可以在设计 ...

  3. C#设计模式(7)——适配器模式(Adapter Pattern)

    一.引言 在实际的开发过程中,由于应用环境的变化(例如使用语言的变化),我们需要的实现在新的环境中没有现存对象可以满足,但是其他环境却存在这样现存的对象.那么如果将“将现存的对象”在新的环境中进行调用 ...

  4. Java(Android)编程思想笔记02:组合与继承、final、策略设计模式与适配器模式、内部类、序列化控制(注意事项)

    1.组合和继承之间的选择 组合和继承都允许在新的类中放置子对象,组合是显式的这样做,而继承则是隐式的做. 组合技术通常用于想在新类中使用现有类的功能而非它的接口这种情形.即在新类中嵌入某个对象,让其实 ...

  5. 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern)

    原文:乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) 作者:webabc ...

  6. C#设计模式之七适配器模式(Adapter)【结构型】

    一.引言   从今天开始我们开始讲[结构型]设计模式,[结构型]设计模式有如下几种:适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式.[创建型]的设计模式解决的是对象创建的问题, ...

  7. 8.3 GOF设计模式二: 适配器模式 Adapter

    GOF设计模式二: 适配器模式 Adapter  为中国市场生产的电器,到了美国,需要有一个转接器才能使用墙上的插座,这个转接 器的功能.原理?复习单实例模式  SingleTon的三个关键点  ...

  8. C#设计模式之六适配器模式(Adapter Pattern)【结构型】

    一.引言 从今天开始我们开始讲[结构型]设计模式,[结构型]设计模式有如下几种:适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式.[创建型]的设计模式解决的是对象创建的问题,那[ ...

  9. C#设计模式(7)——适配器模式(Adapter Pattern)(转)

    一.引言 在实际的开发过程中,由于应用环境的变化(例如使用语言的变化),我们需要的实现在新的环境中没有现存对象可以满足,但是其他环境却存在这样现存的对象.那么如果将“将现存的对象”在新的环境中进行调用 ...

  10. 怎样让孩子爱上设计模式 —— 7.适配器模式(Adapter Pattern)

    怎样让孩子爱上设计模式 -- 7.适配器模式(Adapter Pattern) 标签: 设计模式初涉 概念相关 定义: 适配器模式把一个类的接口变换成client所期待的还有一种接口,从而 使原本因接 ...

随机推荐

  1. 表单的自动到json与urlstr

    将表单序列化成json,将json转换成字符串 //将表单序列化成json 字符串 $.fn.serializeObject = function(){ var obj = {}; var count ...

  2. 最短路算法之Dijkstra算法通俗解释

    Dijkstra算法 说明:求解从起点到任意点的最短距离,注意该算法应用于没有负边的图. 来,看图. 用邻接矩阵表示 int[][] m = { {0, 0, 0, 0, 0, 0}, {0, 0, ...

  3. 使用CEF的JSON解析功能

    Cef提供了JSON解析功能,在cef_parser.h文件内有三个JSON相关的方法: CefParseJSON CefParseJSONAndReturnError CefWriteJSON 以最 ...

  4. 【004】【JVM——垃圾收集算法】

     Java虚拟机学习总结文件夹 垃圾收集算法 垃圾收集算法的实现涉及大量的程序细节,并且各个平台的虚拟机操作内存的方法又各不同样,介绍几种垃圾收集算法的思想及其发展过程. 标记-清除算法 垃圾收集 ...

  5. 怎样获取HTML5视频的持续时间

    HTML5视频的Bigger体验是非常令人振奋的,非常easy的道理,不用载入和依赖烦人的Flash或其它第三方插件来播放视频,也是大功一件.我们能够通过自己定义控件对视频进行显示和操控,当中一个常见 ...

  6. TCP/IP具体解释--UDP数据报中的IP分片

    1.UDP首部 2.UDP分片 在第二章,讲链路层是,提到过以太网.刨除数据帧帧头.最多传输的长度为1500.也就是说,假设一个ip数据报,长度大于1500,则须要分片. 分片方法: 在ip头中3位标 ...

  7. NHibernate3剖析:Configuration篇之SessionFactory lambda配置

    概览 在NHibernate3.0中.SessionFactory的Properties和Cache配置实现了流配置(fluent-configuration)和lambda表达式配置(lambda- ...

  8. Java并发与同步

    Java中并发的形式无非是多线程和多进程两种形式.这两种形式都是能够利用多核来发挥计算能力的. 先说并发: 多进程意味着同一时候执行多个JVM.这个代价通常比多线程高,每一个JVM都有自己的堆栈.都要 ...

  9. Struts2报错org.apache.jasper.JasperException: Invalid directive原因

    struts标签书写错误.<s:textfield name="us.username"/>对的<s:textfield name="us.userna ...

  10. laravel会话驱动扩展—连接自定义会话管理系统

    laravel 版本:5.3.* 用laravel开发公司信息系统过程中,由于业务或安全问题的考虑,会有一些特殊的用户会话管理方面的需求,如多个子系统会话统一管理或A系统业务操作导致B系统中某些在线用 ...