• 设计模式 —— 适配器


    适配器也属于“接口隔离”模式的一种。

    动机

    • 在软件系统中,由于应用环境的变化,常需要将“一些现存的对象”放在新的环境中应用,但是新环境要求的接口是对这些现存对象不满足的。
    • 如何应对这种“迁移的变化”?如何既能利用现有对象的良好实现,同时又能满足新的应用环境所要求的接口?

    生活中的Adapter

     模式定义

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

    适配器模式的使用场景

    • 使用一个已经存在的类,如果他的接口和你要求的不一致时,可以考虑适配器模式;
    • 要在调用者和功能提供者双方都不太容易修改时再使用适配器模式,而不是一有不同就使用它。

    UML类图

     类适配器

     适配器Adapter继承自Target和Adaptee类,Adapter类需要重写Target类的Request函数,在Request中做适当的处理,调用Adaptee类的SepcificRequest。最终,Target实际调用的是Adaptee的SpecificRequest来完成Request的,完成适配;这种叫做类适配器。

     对象适配器

     适配器Adapter类继承自Target类,同时,在Adapter类中有一个Adaptee类型的成员变量;Adapter类重写Request函数时,在Request中,使用Adaptee类型的成员变量调用Adaptee的SpecificRequest函数,最终完成适配;这种叫做对象适配器。

    类适配器和对象适配器的比较

    既然有了类适配器和对象适配器,那么在实际中如何在二者之间做选择呢?

    类适配器有以下特点:

    1. 由于Adapter直接继承自Adaptee类,所以,在Adapter类中可以对Adaptee类的方法进行重定义;
    2. 如果在Adaptee中添加了一个抽象方法,那么Adapter也要进行相应的改动,这样就带来高耦合;
    3. 如果Adaptee还有其它子类,而在Adapter中想调用Adaptee其它子类的方法时,使用类适配器是无法做到的。

    对象适配器有以下特点:

    1. 有的时候,你会发现,不是很容易去构造一个Adaptee类型的对象;
    2. 当Adaptee中添加新的抽象方法时,Adapter类不需要做任何调整,也能正确的进行动作;
    3. 可以使用多肽的方式在Adapter类中调用Adaptee类子类的方法。

    由于对象适配器的耦合度比较低,所以在很多的书中都建议使用对象适配器。在我们实际项目中,也是如此,能使用对象组合的方式,就不使用多继承的方式。

    对象适配器代码实现

     1 #include <iostream>
     2 using namespace std;
     3 
     4 class Target
     5 {
     6 public:
     7     Target(){}
     8     virtual ~Target(){}
     9     virtual void Request()
    10     {
    11         cout<<"Target::Request"<<endl;
    12     }
    13 };
    14 
    15 class Adaptee
    16 {
    17 public:
    18     void SpecificRequest()
    19     {
    20         cout<<"Adaptee::SpecificRequest"<<endl;
    21     }
    22 };
    23 
    24 class Adapter : public Target
    25 {
    26 public:
    27     Adapter() : m_Adaptee(new Adaptee) {}
    28 
    29     ~Adapter()
    30     {
    31         if (m_Adaptee != NULL)
    32         {
    33             delete m_Adaptee;
    34             m_Adaptee = NULL;
    35         }
    36     }
    37 
    38     void Request()
    39     {
    40         m_Adaptee->SpecificRequest();
    41     }
    42 
    43 private:
    44     Adaptee *m_Adaptee;
    45 };
    46 
    47 int main(int argc, char *argv[])
    48 {
    49     Target *targetObj = new Adapter();
    50     targetObj->Request();
    51 
    52     delete targetObj;
    53     targetObj = NULL;
    54 
    55     return 0;
    56 }

    要点总结

    • Adpater模式主要应用余“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况”,在遗留代码复用,类库迁移等方面非常有用。
    • GOF 23定义了对象适配器和类适配器,类适配器采用多继承方式实现,一般不推荐。对象适配器采用对象组合方式,更符合松耦合精神。
  • 相关阅读:
    10.25T2 二维线段树
    10.25T1 模拟+栈
    10.24T3 解方程 取模意义下运算+秦九韶算法
    10.24T2 树链剖分
    10.24T1 树形DP
    10.23T3 杨辉三角上做莫队
    10.23T2 二分+二分图(滑稽)
    10.23T1 杨辉三角
    10.22T6 水题
    10.22T4 模拟DP
  • 原文地址:https://www.cnblogs.com/y4247464/p/15499467.html
Copyright © 2020-2023  润新知