C++设计模式——适配器模式

来源:互联网 发布:淘宝基础版全屏装修 编辑:程序博客网 时间:2024/06/05 02:07

C++设计模式——适配器模式

概念

在计算机编程中,适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。

场景描述

    想了半天没有一个更加贴切的例子,那就继续用网上用的最广泛的例子:插头适配器。某电器现在有个三爪的插头,但是某个插线板上全是双孔的。这么尴尬的情况下,如果要使用这个电器该怎么办呢?我们不可能去再买一个同样的却带着三爪插头的电器,我们也不想花高价钱买一个具有三孔的插线板。所以市场上出现了一种产品,就是插头的适配器,(想起了马云的一句话,你做不好的东西,肯定有别人来替你把它做好)。它给三爪的插头提供三个插孔,给双孔的插座提供两个插头。这样三爪的插头就可以在双孔的插座上使用了。
    类似如此场景,一个类想实现某个功能(两孔插座想实现三爪插头电器的功能),但是另外一个类已经具有该功能(三爪插头电器已经具备两孔插板想实现的所有功能),但是直接使用又有点问题(两孔的插板没办法直接使用三爪插头的电器)。这个时候我们只需要提供一个适配器(插头适配器),就可实现该需求。

类适配器模式和对象适配器模式

    适配器模式的实现分为两种:类适配器和对象适配器。类适配器是通过类的多继承来实现的,对象适配器则是通过类之间的组合来实现的。两种模式的特点也和这两种模式的实现特点有点关系,我们通过类图来总结一下两者的特点。

类图描述

类适配器:

类适配器

类适配器的特点:

  • 由于类适配器通过类继承来实现,所以受父类影响会比较大,假如父类中添加一个抽象方法的时候,适配器类也需要添加。

  • 如果直接继承的是被适配类的基类,那么当适配器想要调用被适配器中某个子类的方法额时候,无法做到。

对象适配器:

对象适配器

相比类适配器,对象适配器的特点:

  • 避免了类适配器高耦合的情况。当被适配器中添加抽象方法的时候,对适配器无影响。

  • 通过多态特性,适配器类中可以调用被适配基类的子类方法。

具体实现

类适配器的实现
//adapter.h

#ifndef ADAPTER_H_#define ADAPTER_H_#include <iostream>using namespace std;//双孔插板类class SocketWith2Hole{public:    virtual void PowerOn()//提供电能    {        cout << "通过两孔插座提供电源" << endl;    }};//三爪插头类class PlugWith3Hand{public:    void Use3Hand()//使用三爪获得电能    {        cout << "使用三爪插头获得电源" << endl;    }};
//适配器类 把双孔插座的接口改成三口插座,并调用三爪插头。class Adapter : public SocketWith2Hole, public PlugWith3Hand{public:    virtual void PowerOn()//    {        cout << "通过三孔插座提供电源" << endl;        Use3Hand();    }};

对象适配器的实现,只需要将适配器类修改成如下实现即可:

class Adapter : public SocketWith2Hole{public:    Adapter()    {        m_plug = new PlugWith3Hand();    }    ~Adapter()    {        if (NULL != m_plug)        {            delete m_plug;            m_plug = NULL;        }    }    virtual void PowerOn()    {        cout << "通过三孔插座提供电源" << endl;        m_plug->Use3Hand();    }private:    PlugWith3Hand* m_plug;};

客户端调用

#include "Adapter.h"#ifndef DELETE_OBJECT#define DELETE_OBJECT(Obj) \        {\        if (Obj) \            {\            delete (Obj); \            (Obj)=NULL;\            }\        }#endifint main(){    SocketWith2Hole* soket = new SocketWith2Hole();    soket->PowerOn();    Adapter* adapter = new Adapter();    adapter->PowerOn();    DELETE_OBJECT(adapter);    return 0;    };

优缺点

优点:

  • 提高了类的复用性

  • 很灵活, 可以让无关联的类一起运行。

缺点:

  • 很明显适配器模式是一种补救的模式,如果过度使用,会使得整个系统代码变得难以阅读和维护。

适用场景

  • 从场景描述中可以了解到,当想使用一个类的接口,但是该接口无法直接使用的时候。

  • 从对象适配器特点中可以看出,当想使用一个类的子类中的功能的时候,我们不需要对每个要使用的类都子类化之后使用,只需要通过对象适配器即可。

  • 或者是你想创建一个复用性很高的类,该类可以与其他任何不相关和不可预见的类协同工作。

原创粉丝点击