结构型模式 - 适配器模式(ADAPTER)

1. 模式的定义与特点

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

适配器模式分为类结构型模式和对象结构型模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。

该模式的主要优点如下。

  • 客户端通过适配器可以透明地调用目标接口。
  • 复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类。
  • 将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题。
  • 在很多业务场景中符合开闭原则。


其缺点是:

  • 适配器编写过程需要结合业务场景全面考虑,可能会增加系统的复杂性。
  • 增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱。

2. 别名

包装器Wrapper

3. 动机

有时,为复用而设计的工具箱类不能够被复用的原因仅仅是因为它的接口与专业应用领域所需要的接口不匹配。

4. 模式的结构与实现

类适配器模式可采用多重继承方式实现,如 C++ 可定义一个适配器类来同时继承当前系统的业务接口和现有组件库中已经存在的组件接口;Java 不支持多继承,但可以定义一个适配器类来实现当前系统的业务接口,同时又继承现有组件库中已经存在的组件。

对象适配器模式可釆用将现有组件库中已经实现的组件引入适配器类中,该类同时实现当前系统的业务接口。现在来介绍它们的基本结构。

1. 模式的结构

适配器模式(Adapter)包含以下主要角色。

  1. 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
  2. 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。
  3. 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。

共有两类适配器模式:

1. 对象适配器模式

-- 在这种适配器模式中,适配器容纳一个它包裹的类的实例。在这种情况下,适配器调用被包裹对象的物理实体

2. 类适配器模式

-- 这种适配器模式下,适配器继承自已实现的类(一般多重继承)。

5. 示例代码

5.1 类适配器样例

class Target
{
public:
    // Methods
    virtual void Request(){};
};

// "Adaptee"
class Adaptee
{
public:
    // Methods
    void SpecificRequest()
    {
        cout<<"Called SpecificRequest()"<<endl;
    }
};

// "Adapter"
class Adapter : public Adaptee, public Target
{
public:
    // Implements ITarget interface
    void Request()
    {
        // Possibly do some data manipulation
        // and then call SpecificRequest
        this->SpecificRequest();
    }
};
int main()
{
    // Create adapter and place a request
    Target *t = new Adapter();
    t->Request();
    return 0;
}

5.2 对象适配器样例

// "ITarget"
class Target
{
public:
    // Methods
    virtual void Request(){};
};

// "Adaptee"
class Adaptee
{
public:
    // Methods
    void SpecificRequest()
    {
        cout<<"Called SpecificRequest()"<<endl;
    }
};

// "Adapter"
class Adapter : public Target
{
private:
    Adaptee *adaptee;
public:
    Adapter()
    {
        adaptee = new Adaptee();
    }
    // Implements ITarget interface
    void Request()
    {
        // Possibly do some data manipulation
        // and then call SpecificRequest
        adaptee->SpecificRequest();
    }
};
int main()
{
    // Create adapter and place a request
    Target *t = new Adapter();
    t->Request();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/rukawashan/article/details/124549783