C++结构型模式-适配器模式

1.1 基本概念

适配器模式(Adapter Pattern):或称为包装器(Wrapper)将一个接口转换为客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,

适配器模式包括类适配器和对象适配器。

1.2 模式结构

1、Target(目标抽象类) :目标抽象类定义客户要用的特定领域的接口,可以是个抽象类或接口,也可以是个具体类;

2、Adapter(适配器类):可以调用另一个接口,作为一个转换器,对适配者类和目标抽象类进行适配。

(1)类适配器中,适配器类通过实现Target接口并继承 Adaptee类,使得两者产生联系;

(2)对象适配器类中,适配器类通过继承Target,并关联一个Adaptee对象使两者产生联系;

3、Adaptee (适配者类)

被适配的角色,它定义了一个已经存在的接口,这个接口需要适配。

4、Client(客户类)

针对目标抽象类进行编程,调用在抽象目标类中定义的业务方法。

(1)类适配器模式结构:适配器类Adapter,实现了抽象目标类(Target)接口,并继承了适配者类(Adaptee),在适配器类 的request()方法中调用所继承的适配者类(Adaptee)的SpeaificRequest()方法,实现了适配的目的。

(2)对象适配器模式结构

 为了使客户端能够使用适配者类Adapte 的 spcificRequest()方法,需要提供一个适配器类Adapter,这个适配器类包装了一个适配者的实例,从而将客户端和适配者衔接起来,在适配器的request()方法中调用适配者的 spcificRequest()方法。适配器类和适配者类为关联关系。

1.3 优缺点

优点:

  1. 将目标类和适配器类解耦。通过引入一个适配器类来重用现有的适配者类,而无须修改原有的代码。
  2. 增加了类的透明性和复用性,将具体的实现封装在适配器类中,对于客户端类来说是透明的,而且提高了适配器的复用性。
  3. 灵活性和扩展性都非常好,符合开闭原则

缺点:

  1. 一次最多只能适配一个适配器类,不能同时适配多个适配器。
  2. 适配器类不能为最终类。
  3. 目标抽象类只能为接口,不能为类,其使用有一定的局限性。

1.4 应用场景

(1)系统需要使用现有的类,而这些类的接口不符合系统的需求;

(2)数据库链接工具JDBC,使得使用Java语言程序能够与数据库链接,并使用SQL语言来查询和操作数据库。

1.5 实例

1.5.1 类适配器模式

设计一个可以模拟各种动物的机器人,在机器人中定义了一系列方法,如机器人叫喊 cry()方法,机器人移动方法 move,现在在不修改已有代码的情况下,使得机器人能够像狗一样,叫 wang()和跑 move()


#include <iostream>
using namespace std;
/*目标抽象类RobotTarget  机器人接口*/
class RobotTarget{
public:
	RobotTarget(){};
	virtual void cry()=0;

	virtual void move()=0;
	~RobotTarget(){};
};

/*适配者类 DogAdaptee*/
class DogAdaptee{
public:
DogAdaptee(){}
virtual void wang()
{
	cout<<"wang wang"<<endl;
}

virtual void run()
{
	cout<<"run run"<<endl;
}
};

/*适配器类  仿生狗 DogAdapter*/
class DogAdapter: public RobotTarget, public DogAdaptee{
public:
	DogAdapter(){};

	virtual void cry()
	{
		wang();
	}

	virtual void move()
	{
		run();
	}
};

 int main()
{
 //对象适配器
	RobotTarget* robot= new DogAdapter();

	robot->cry();
	robot->move();
    
	delete robot;
    return 0;
}

1.5.2 对象适配器模式

英式插座与中式插座规格不同,如何在不修改英式插座的基础上转换为中式插座。

#include <iostream>
#include <string>

using namespace std;

//目标抽象类 CCnOutlet中式插座
class CCnOutlet
{
public:
    virtual ~CCnOutlet()
    {

    }

    virtual void Cnplug() = 0;
};

//适配者类 CEnOutlet
class CEnOutlet
{
public:
    virtual ~CEnOutlet()
    {

    }

    virtual void Enplug()
    {
        cout << "British socket!" << endl;
    }
};

//适配器类
class CCnOutletAdapter : public CCnOutlet
{
public:
    CCnOutletAdapter(CEnOutlet *pEnOutlet) : m_pEnOutlet(pEnOutlet){};

    virtual ~CCnOutletAdapter(){};

    virtual void Cnplug()
    {
        m_pEnOutlet->Enplug();
        cout << "adapter" << endl;
    }

private:
    CEnOutlet *m_pEnOutlet;
};

int main(int argc, char **argv)
{
    CEnOutlet *pEnOutlet = new CEnOutlet;
    CCnOutlet *pCnOutlet = new CCnOutletAdapter(pEnOutlet);

    //英式插座适配中式插座
    pCnOutlet->Cnplug();

    delete pEnOutlet;
    delete pCnOutlet;

    return 0;
}

参考文献:

【1】https://www.jianshu.com/p/b8d3142772e0

【2】C++设计模式-Adapter适配器模式(转) 

【3】C++设计模式3-适配器模式Adapter | Veaxen's 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
适配器模式是一种结构型设计模式,它允许你将不兼容的对象包装在一个适配器中,以使其与另一个类兼容。 在 C++ 中,适配器模式可以通过类适配器和对象适配器来实现。 类适配器使用多重继承来实现适配器和目标类的接口之间的转换。适配器类继承目标类和适配器接口类,并实现适配器接口类的方法,将目标类的方法转换为适配器接口类的方法。 例如,假设我们有一个 `Target` 类和一个 `Adaptee` 类,它们的接口不兼容。我们可以创建一个 `Adapter` 类,它继承 `Target` 类并实现 `Adaptee` 类的方法,将 `Adaptee` 类的方法转换为 `Target` 类的方法。 ```c++ class Target { public: virtual void request() = 0; }; class Adaptee { public: void specificRequest() { std::cout << "Adaptee specific request" << std::endl; } }; class Adapter : public Target, private Adaptee { public: void request() override { specificRequest(); } }; ``` 对象适配器使用组合来实现适配器和目标类的接口之间的转换。适配器类包含一个目标类的实例,并实现适配器接口类的方法,将目标类的方法转换为适配器接口类的方法。 例如,我们可以创建一个 `Adapter` 类,它包含一个 `Adaptee` 类的实例,并实现 `Target` 类的方法,将 `Target` 类的方法转换为 `Adaptee` 类的方法。 ```c++ class Adapter : public Target { public: Adapter(Adaptee* adaptee) : m_adaptee(adaptee) {} void request() override { m_adaptee->specificRequest(); } private: Adaptee* m_adaptee; }; ``` 使用适配器模式可以使我们在不修改现有代码的情况下,将旧接口转换为新接口,从而使不兼容的类能够协同工作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值