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

适配器模式是软件设计中的结构型模式之一,用于解决接口不兼容问题,使得原本无法协同工作的类可以一起工作。文章介绍了适配器模式的概念、生活中的例子,以及在C++中如何通过继承和复合来实现适配器模式,并指出过度使用适配器可能带来的系统混乱问题。适配器模式常见于旧系统类接口与新系统需求不匹配或使用第三方组件接口改造的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在软件工程中,设计模式(Design Pattern)是对软件设计普遍存在(反复出现)的各种问题,锁提出的解决防范。根据模式的目的来划分的话,GoF(Gang of Four) 设计模式可以分为以下三种类型:

在这里插入图片描述

1.创建型模式:用来描述“如何创建对象”,它的主要特点是“将对象的创建和使用分离”。包括单例、原型、工厂方法、抽象工厂和建造者5种模式。

2.结构型模式:用来描述如何将类或对象按照某种布局组成更大的结构。包括代理、适配器、侨接、装饰、外观、享元和组合7种模式。

3.行为型模式:用来识别对象之间的常用交流模式以及如何分配职责。包括模版方法、策略、命令、职责链、状态、观察者、中介者、迭代器、访问者、备忘录和解释器11种模式。

今天介绍1种常用的设计模式。

适配器模式(Adapter)

在实际生活中,也存在适配器的使用场景,比如:港式插头转换器、电源适配器和USB转接口。而在软件工程中,适配器模式的作用是解决两个软件实体间的接口不兼容的问题。使用适配器模式之后,原本由于接口不兼容的两个软件实体就可以一起工作。工程中,通俗的讲就是我们已经有了一些类,而这些类不能满足新的需求,此时就可以考虑是否能将现有的类适配成可以满足新需求的类。适配器类需要继承或依赖已有的类,实现想要的目标接口。

缺点:过多地使用适配器,会让系统非常凌乱,不易整体进行把握。比如,明明看到调用的是A接口,其实内部适配成了B接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。

使用复合实现适配器模式

/*
	关键代码:适配器继承或依赖已有的对象,实现想要的目标接口。
	以下示例中,假设我们之前有了一个双端队列,新的需求要使用栈和队列来完成。
	双端队列可以在头尾删减或增加元素。而栈是一种先进后出的数据结构,添加数据时添加到栈的顶部,删除数据时先删顶部的数据。因此我们完全可以将一个现有的双端队列适配成一个栈。
*/

//双端队列, 被适配类
class Deque {
  public:
  	void push_back(int x) {
      cout << "Deque push_back:" << x << endl;
    }
  
  	void push_front(int x) {
      cout << "Deque push_front:" << x << endl;
    }
  
  	void pop_back() {
      cout << "Deque pop_back" << endl;
    }
  
  	void pop_front() {
      cout << "Deque pop_front" << endl;
    }
};

//顺序类, 抽象目标类
class Sequence {
  public:
  	virtual void push(int x) = 0;
  	virtual void pop() = 0;
};

//栈,后进先出,适配类
class Stack:public Sequence {
  public:
  //将元素添加到堆栈的顶部
  void push(int x) override {
    	m_deque.push_front(x);
  }
  //从堆栈中删除顶部元素
  void pop() override {
    m_deque.pop_front();
  }
  
 private:
  Deque m_deque;
};

//队列,先进先出,适配类
class Queue:public Sequence {
  public:
  	// 将元素添加到队列尾部
  	void push(int x) override {
      m_deque.push_back(x);
    }
  // 从队列中删除顶部元素
  	void pop() override {
      m_deque.pop_front();
    }
  private:
  	Deque m_deque;
}

使用继承实现适配器模式

// 双端队列,被适配类
class Deque {
	public:
  	void push_back(int x) {
      cout << "Deque push_back:"<< x << endl;
    }
  	void push_front(int x) {
      cout <<"Deque push_front:"<< x << endl;
    }
  	void pop_back() {
       cout << "Deque pop_back" << endl;
    }
  	void pop_front() {
      	cout << "Deque pop_front" << endl;
    }
};

//顺序类,抽象目标类
class Sequence {
  public:
  	virtual void push(int x) = 0;
  	virtual void pop() = 0;
};

//栈,后进先出,适配类
class Stack:public Sequence, private Deque {
  public:
  	void push(int x) {
      push_front(x);
    }
  	void pop() {
      pop_front();
    }
};

//队列,先进先出,适配类

class Queue:public Sequence, private Deque {
  public:
  	void push(int x){
      push_back(x);
    }
  	void pop() {
      pop_front();
    }
};

应用场景:

以前开发的系统存在满足新系统功能需求的类,但其接口同新系统的接口不一致。

使用第三方提供的组件,但组件接口定义和自己要求的接口定义不同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值