《大话设计模式》C++实现:17 适配器模式

1、 适配器模式是什么?

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

2、 为何要使用适配器模式?

在软件开发中,系统的数据和行为都正确,但接口不符时,我们需要考虑适配器,目的:是控制范围之外的一个原有对象与某个接口匹配。
主要应用在希望服用一些现存的类,但是接口又与复用环境要求不一致的情况。
如:在早期对代码笃用一些功能等应用上很有实际价值。

3、 如何使用适配器模式?

step1:适配器将待匹配对象作为它的私有成员,
step2:在适配器的构造函数中对待适配对象进行初始化,析构函数中析构待适配对象;
step3:在公共的目标接口中,调用待匹配对象对应接口函数,实现点对点适配。

简单的UML图:
在这里插入图片描述

4、 怎样才能用好适配器模式?

(1)在双方都不太容易修改时在使用适配器模式适配
(2)使用第三方软件开发组件,该组件的接口与我们自己系统接口不一致
(3)使用适配器的原则小结:

  • 如果能事先预防接口不同的问题,接口不匹配就不会发生;
  • 在有小的接口不统一问题发生时,即使重构,问题不至于扩大;
  • 只有碰到无法改变原有设计合代码的情况下,才考虑适配。
  • 事后控制不如始终事中控制,事中控制不如事前控制。
5、实例-篮球翻译适配器

(1)UML类图
在这里插入图片描述
(2)核心实现思路

step1:适配器(翻译员)将待匹配对象(外籍球员)作为它的私有成员,
step2:在适配器(翻译员)的构造函数中对待适配对象(外籍球员)进行初始化(分配内存空间+球员名字),析构函数中析构待适配对象(外籍球员);
step3:在公共的目标接口Attack,Defense中,调用待匹配对象(外籍球员)对应能明白的"进攻"、"防守"函数,实现点对点适配。

(3)主要代码如下:
1.1、IPlayer.h

#pragma once
#include <string>
using namespace std;

class IPlayer
{
public:
	IPlayer();
	IPlayer(const string& _name);
	~IPlayer();
public:
	virtual void Attack();//接口:进攻
	virtual void Defense();//防守
protected:
	string name;
};

1.2 IPlayer.cpp

#include "IPlayer.h"
#include <iostream>


IPlayer::IPlayer()
{
}


IPlayer::IPlayer(const string& _name)
	:name(_name)
{

}

IPlayer::~IPlayer()
{
}

void IPlayer::Attack()
{
	cout << "进攻" << endl;
}

void IPlayer::Defense()
{
	cout << "防守" << endl;
}

2.1 ITranslater.h

#pragma once
#include "IPlayer.h"
#include "ForeignCenter.h"

class ITranslater :
	public IPlayer
{
public:
	ITranslater();
	ITranslater(const string& _name);
	~ITranslater();
	virtual void Attack() override;//公共接口
	virtual void Defense() override;

private:
	ForeignCenter* m_pForeignCenter;
};

2.2 ITranslater.cpp

#include "ITranslater.h"



ITranslater::ITranslater()
{

}


ITranslater::ITranslater(const string& _name)
	:IPlayer(_name)
{
	m_pForeignCenter = new ForeignCenter();
	m_pForeignCenter->setName(_name);
}

ITranslater::~ITranslater()
{
	delete m_pForeignCenter;
	m_pForeignCenter = nullptr;
}

void ITranslater::Attack()
{
	m_pForeignCenter->进攻();
}

void ITranslater::Defense()
{
	m_pForeignCenter->防守();
}

3.1 ForeignCenter.h

#pragma once
#include <string>
using namespace std;

class ForeignCenter
{
public:
	ForeignCenter();
	~ForeignCenter();
public:
	void 进攻();
	void 防守();
public:
	string getName();
	void setName(const string& _name);
private:
	string name;
};

3.2 ForeignCenter.cpp

#include "ForeignCenter.h"
#include <iostream>


ForeignCenter::ForeignCenter()
{
}


ForeignCenter::~ForeignCenter()
{
}

void ForeignCenter::进攻()
{
	cout << "外籍中锋-" << name << ",进攻" << endl;
}

void ForeignCenter::防守()
{
	cout << "外籍中锋-" << name << ",防守" << endl;
}

std::string ForeignCenter::getName()
{
	return name;
}

void ForeignCenter::setName(const string& _name)
{
	name = _name;
}

4、main.cpp

#include "IPlayer.h"
#include "Forwards.h"
#include "Center.h"
#include "Guards.h"
#include "ITranslater.h"

#include <iostream>
void test2()
{
	cout << "=============test2()=============" << endl;
	IPlayer* pPlayer = new Forwards("巴蒂尔");
	pPlayer->Attack();
	IPlayer* pPlayer1 = new Guards("麦克格雷迪");
	pPlayer1->Attack();

	IPlayer* pPlayer2 = new ITranslater("姚明");//这个ITranslater翻译家就是姚明(外籍球员)的适配器。可以很好地适配到英语环境中去~~
	pPlayer2->Attack();
	pPlayer2->Defense();
}

int main()
{
	test2();
	system("pause");
	return 0;
}

在这里插入图片描述

此为《大话设计模式》学习心得系列 P171~~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值