设计模式-06.ADAPTER(适配器)— 类对象结构型模式

1 意图

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

2 别名

包装器 Wrapper

3 动机

一个应用可能会有一些类具有不同的接口并且这些接口互不兼容,在这样的应用中象 TextView 这样已经存在并且不相关的类如何协同工作呢?我们可以改变 TextView 类使它兼容 Shape 类的接口,但前提是必须有这个工具箱的源代码。然而即使我们得到了这些源代码,修改 TextView 也是没有什么意义的;因为不应该仅仅为了实现一个应用,工具箱就不得不采用一些与特定领域相关的接口。
图一

4 适用性

  • 你想使用一个已经存在的类,而它的接口不符合你的需求。
  • 你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
  • (仅适用于对象 Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。

5 结构

  • 类适配器使用多重继承对一个接口与另一个接口进行匹配
    图二
  • 对象匹配器依赖于对象组合
    图三

6 参与者

  • Target(Shape)
    • 定义 Client 使用的与特定领域相关的接口。
  • Client(DrawingEditor)
    • 与符合 Target 接口的对象协同。
  • Adaptee(TextView)
    • 定义一个已经存在的接口,这个接口需要适配。
  • Adapter(TextShape)
    • 对 Adaptee 的接口与 Target 接口进行适配。

7 协作

Client 在 Adapter 实例上调用一些操作。接着适配器调用 Adaptee 的操作实现这个请求。

8 效果

  • 类适配器
    • 用一个具体的 Adapter 类对 Adaptee 和 Target 进行匹配。结果是当我们想要匹配一个类以及所有它的子类时,类 Adapter 将不能胜任工作。
    • 使得 Adapter 可以重定义 Adaptee 的部分行为,因为 Adapter 是 Adaptee 的一个子类。
    • 仅仅引入了一个对象,并不需要额外的指针以间接得到 Adaptee。
  • 对象适配器
    • 允许一个 Adapter 与多个 Adaptee 即Adaptee本身以及它的所有子类(如果有子类的话)。
    • 同时工作 Adapter 也可以一次给所有的 Adaptee 添加功能。
    • 使得重定义 Adaptee 的行为比较困难。这就需要生成 Adaptee 的子类并且使得 Adapter 引用这个子类而不是引用 Adaptee 本身。

9 实现

  • 使用 C++ 实现适配器类
  • 可插入的适配器
    • 使用抽象操作
      图四
    • 使用代理对象
      图五
    • 参数化的适配器

10 代码示例

  • Target

    1
    2
    3
    4
    interface ITarget
    {
    void Request();
    }
  • Adaptee

    1
    2
    3
    4
    5
    6
    7
    class Adaptee
    {
    public void SpecificRequest()
    {
    Console.WriteLine("适配的对象");
    }
    }
  • Adapter
    类适配器

    1
    2
    3
    4
    5
    6
    7
    class ClassAdapter : Adaptee, ITarget
    {
    public void Request()
    {
    Console.WriteLine("目标对象");
    }
    }

    对象适配器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class ObjectAdapter : ITarget
    {
    private Adaptee adaptee = null;

    public ObjectAdapter(Adaptee adaptee)
    {
    this.adaptee = adaptee;
    }

    public void Request()
    {
    Console.WriteLine("目标对象");
    }

    public void SpecificRequest()
    {
    adaptee.SpecificRequest();
    }
    }
  • Client

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class Client
    {
    public static void Main(string[] args)
    {
    Console.WriteLine("========类适配器=========");
    ClassAdapter classAdapter = new ClassAdapter();
    classAdapter.Request();
    classAdapter.SpecificRequest();

    Console.WriteLine("========对象适配器=========");
    Adaptee adaptee=new Adaptee();
    ObjectAdapter objectAdapter=new ObjectAdapter(adaptee);

    objectAdapter.Request();
    objectAdapter.SpecificRequest();

    Console.ReadLine();
    }
    }

11 已知应用

各类第三方接口

12 相关模式

  • Bridge 模式的结构与对象适配器类似,但是 Bridge 模式的出发点不同:Bridge 目的是将接口部分和实现部分分离,从而对它们可以较为容易也相对独立的加以改变。而 Adapter 则意味着改变一个已有对象的接口。
  • Decorator 模式增强了其他对象的功能而同时又不改变它的接口。因此 decorator 对应用程序的透明性比适配器要好。结果是 decorator 支持递归组合,而纯粹使用适配器是不可能实现这一点的。
  • Proxy 模式不改变它的接口的条件下,为另一个对象定义了一个代理。
坚持原创技术分享,您的支持将鼓励我继续创作!