Linux C++ 064-设计模式之适配器模式
本节关键字:Linux、C++、设计模式、设配器模式
相关库函数:
概念
在计算机编程中,适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适配器模式的宗旨:保留现有类所提供的服务,向客户提供接口,以满足客户的期望。客户需要调用我们的代码的对象。
基本信息
共有两类适配器模式:对象适配器模式、类适配器模式。
对象适配器模式
在这种适配器模式中,适配器容纳一个它包裹的类的实例。在这种情况下,适配器调用被包裹对象的物理实体。对象适配器”通过组合除了满足“用户期待接口”还降低了代码间的不良耦合。在工作中推荐使用“对象适配”。
类适配器模式
这种适配器模式下,适配器继承自已实现的类(一般多重继承)。当客户在接口中定义了他期望的行为时,我们就可以应用适配器模式,提供一个实现该接口的类,并且扩展已有的类,通过创建子类来实现适配。
缺省适配器模式
缺省适配器模式是一种特殊的适配器模式,但这个适配器是由一个抽象类实现的,并且在抽象类中要实现目标接口中所规定的所有方法,但很多方法的实现都是“平庸”的实现,也就是说,这些方法都是空方法。而具体的子类都要继承此抽象类。
代码示例
// 将一个接口转化成用户希望的另一个接口,使得原来不兼容不能在一起工作的类可以在一起工作。(容器适配器)
// 目标类不能满足要求,适配器类继承现有的目标类,使得现有的目标类适配成满足要求的类
// 例子:用现有的双端队列适配成栈、队列
// 在该例中,Sequence作为目标类,Stack或者Queue作为适配器,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
{
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 Deque2
{
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 Sequence2
{
public:
virtual void push(int x) = 0;
virtual void pop() = 0;
};
// 栈,后进先出, 适配类
class Stack2 : public Sequence2, private Deque2
{
public:
void push(int x) {
push_front(x);
}
void pop() {
pop_front();
}
};
// 队列,先进先出,适配类
class Queue2 : public Sequence2, private Deque2
{
public:
void push(int x) {
push_back(x);
}
void pop() {
pop_front();
}
};