通过例子学设计模式之--适配器模式以及使用场景说明(C++实现)

          适配器模式的定义:适配器模式将一个类的接口转换成客户期望的另一个接口,让原本不兼容的接口可以合作无间。
          该模式应该好理解。比如电源适配器(中国和欧洲分别是电源220V,110V)就是该模式的一种表现。关于类图或者其他说明我这边就不啰嗦了。很多开发者包括我自己也是,更多困惑是不知道在实际的项目中该如何使用设计模式。本文希望通过例子来说明什么情况下使用适配器模式,算是抛砖引玉吧。
          使用场景:我们准备开发一个新模块或者功能。现在的情况是我们已经有现成可用的模块或者第三方库,这些模块经过客户测试是完全符合需求的,而且是稳定的。当然大家都希望直接调用这些模块,而不是费时费力的从头开发。问题是通过分析现有模块的接口或者第三方库的时候,发现直接调用比较麻烦或者不符合现在的编程模式。比如数据结构的定义不一致,比如返回值不一致,比如接口参数不一致(很多时候第三方库考虑各种兼容性,而我们其实不一定需要)。
          怎么办呢?好办,增加一个"中间层"解决。这个中间层就是"适配器模式"。如果不增加这个"中间层",或多或少会打乱我们现有的接口定义或者编码方式。
          实现方式:一般是通过类适配器或者是通过对象适配器。如何区分这2种呢?类适配器是通过"多继承",即继承的方式实现,耦合性很高,父类变化了子类就需要重新编译链接,而且"多继承"容易产生二义性,不建议使用。对象适配器是通过对象组合"的方式实现,耦合性低,通常使用该方式。符合面向对象设计的一个基本原则"优先使用组合,而不是继承"。   
          OK,最后还是通过例子来说明吧:

    
/* 被适配者,Adaptee */
class API3rd
{
public:
	int fun1(int param1,int param2,float f1,float f2)
	{
		printf("API3rd::fun1\r\n");
		return 1;
	}
	float fun2()
	{
		printf("API3rd::fun2\r\n");
		return 0.1;
	}
};

/* Target类 */
class MyClass 
{
public:
	MyClass(){};
	virtual ~MyClass(){}
	virtual int f1(int param1)
	{
		printf("MyClass::f1\r\n");
		return 0;
	}
	virtual int f2()
	{
		printf("MyClass::f2\r\n");
		return 0;
	}
};

/* 类适配器,使用多继承 */
class Adapter1 : private API3rd,private MyClass
{
public:
	virtual int f1(int param1)
	{
		printf("Adapter1::f1\r\n");
		printf("由于API提供的接口参数太多,我们只需要关注一个参数即可。因此使用适配器模式对该接口适配。\r\n");
		return API3rd::fun1(param1,0,0.0,0.0);
	}
	virtual int f2()
	{
		printf("Adapter1::f2\r\n");
		printf("由于API提供的接口的返回值不符合我们的需要,因此使用适配器模式对该接口进行适配\r\n");
		float f = API3rd::fun2();
		return (f+0.5);
	}
};


/* 对象适配器,使用对象组合的方式代替继承 */
class Adapter2 : private MyClass
{
public:
	Adapter2()
	{
		m_api = new API3rd();
	}
	~Adapter2()
	{
		if(m_api)
		{
			delete m_api;
		}
	}
	
	virtual int f1(int param1)
	{
		printf("Adapter2::f1\r\n");
		printf("由于API提供的接口参数太多,我们只需要关注一个参数即可。因此使用适配器模式对该接口适配。\r\n");
		return m_api->fun1(param1,0,0.0,0.0);
	}
	virtual int f2()
	{
		printf("Adapter2::f2\r\n");
		printf("由于API提供的接口的返回值不符合我们的需要,因此使用适配器模式对该接口进行适配\r\n");
		float f = m_api->fun2();
		return (f+0.5);
	}
private:
	API3rd* m_api;
};


/* Client 调用场景 */
void TestAdapter()
{
	Adapter1* ap1 = new Adapter1;
	ap1->f1(2);
	ap1->f2();

	Adapter2* ap2 = new Adapter2;
	ap2->f1(2);
	ap2->f2();

	delete ap1;
	delete ap2;
}

   
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
适配器设计模式是一种结构型设计模式,它用于将一个类的接口转换为客户端所期望的另一个接口。在C语言中,可以通过以下步骤来实现适配器设计模式: 1. 首先,定义目标接口(Target Interface),这是客户端期望的接口。它可以是一个抽象基类或者一个纯虚函数。 ```c // 目标接口 typedef struct { void (*request)(void); } TargetInterface; ``` 2. 接下来,实现需要适配的类(Adaptee Class)。这个类拥有与目标接口不同的接口。 ```c // 需要适配的类 typedef struct { void (*specificRequest)(void); } AdapteeClass; void specificRequestImpl(void) { // 执行特定的操作 } ``` 3. 创建适配器类(Adapter Class),该类继承或包含目标接口,并将其方法委托给适配的类。 ```c // 适配器类 typedef struct { TargetInterface targetInterface; AdapteeClass* adaptee;} AdapterClass; void requestImpl(void) { AdapterClass* adapter = (AdapterClass*)this; adapter->adaptee->specificRequest(); } TargetInterface* createAdapter(AdapteeClass* adaptee) { AdapterClass* adapter = (AdapterClass*)malloc(sizeof(AdapterClass)); adapter->targetInterface.request = requestImpl; adapter->adaptee = adaptee; return &(adapter->targetInterface); } ``` 4. 最后,客户端可以通过目标接口来使用适配器。 ```c int main() { AdapteeClass adaptee; adaptee.specificRequest = specificRequestImpl; TargetInterface* adapter = createAdapter(&adaptee); adapter->request(); return 0; } ``` 上述代码演示了适配器设计模式的简单实现。通过适配器类的创建和使用,客户端可以通过目标接口调用适配的类的方法,实现了将两个不兼容接口之间的适配。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值