当前位置: 首页 > article >正文

C++适配器模式之可插入适配器的实现模式和方法

可插入适配器与Adaptee的窄接口

在C++适配器模式中,可插入适配器(Pluggable Adapter)是指适配器类的设计允许在运行时动态地插入不同的Adaptee对象,从而使适配器具有灵活性和可扩展性。这种设计使得适配器不仅限于适配一个特定的Adaptee,而是可以适配多个不同的Adaptee。

Adaptee的窄接口(Narrow Interface)是指Adaptee提供的接口只包含有限的方法,这些方法可能不足以满足客户端的需求。适配器的工作就是将这些有限的方法适配成客户端所期望的更丰富的接口。

可插入适配器的实现方式

可插入适配器有以下几种实现方式:

  1. 对象适配器模式(Object Adapter):适配器持有Adaptee实例的引用。
  2. 类适配器模式(Class Adapter):适配器通过多重继承同时继承目标接口和Adaptee。
  3. 双适配器模式(Two-Way Adapter):适配器可以同时作为Adaptee和Target接口的适配器。

下面分别介绍这三种实现方式,并给出UML图和C++代码示例。

1. 对象适配器模式(Object Adapter)

UML 类图
+-------------------+           +-------------------+
|      Target       |           |      Adapter      |
|-------------------|           |-------------------|
| + request()       |<----------|>+ request()       |
+-------------------+           |-------------------|
                                  | - adaptee: Adaptee|
                                  |-------------------|
                                  | + request()       |
                                  |-------------------|
                                  | + doSomething()   |
                                  +-------------------+
                                        |
                                        |
                                        V
                                  +-------------------+
                                  |      Adaptee      |
                                  |-------------------|
                                  | + doSomething()   |
                                  +-------------------+

C++ 代码示例
#include <iostream>

// Target 接口
class Target {
public:
    virtual void request() const = 0;
};

// Adaptee 类
class Adaptee {
public:
    void doSomething() const {
        std::cout << "Adaptee: Doing something." << std::endl;
    }
};

// Adapter 类
class Adapter : public Target {
private:
    Adaptee* adaptee;

public:
    Adapter(Adaptee* adaptee) : adaptee(adaptee) {}

    void request() const override {
        adaptee->doSomething();
    }
};

// 客户端代码
int main() {
    Adaptee* adaptee = new Adaptee();
    Target* adapter = new Adapter(adaptee);

    adapter->request(); // 调用适配器的方法

    delete adaptee;
    delete adapter;

    return 0;
}

2. 类适配器模式(Class Adapter)

UML 类图
+-------------------+           +-------------------+
|      Target       |           |      Adapter      |
|-------------------|           |-------------------|
| + request()       |<----------|>+ request()       |
+-------------------+           |-------------------|
                                  | + doSomething()   |
                                  |-------------------|
                                  +-------------------+
                                        ^
                                        |
                                        |
                                  +-------------------+
                                  |      Adaptee      |
                                  |-------------------|
                                  | + doSomething()   |
                                  +-------------------+

C++ 代码示例
#include <iostream>

// Target 接口
class Target {
public:
    virtual void request() const = 0;
};

// Adaptee 类
class Adaptee {
public:
    void doSomething() const {
        std::cout << "Adaptee: Doing something." << std::endl;
    }
};

// Adapter 类
class Adapter : public Target, private Adaptee {
public:
    void request() const override {
        doSomething();
    }
};

// 客户端代码
int main() {
    Target* adapter = new Adapter();

    adapter->request(); // 调用适配器的方法

    delete adapter;

    return 0;
}

3. 双适配器模式(Two-Way Adapter)

UML 类图
+-------------------+           +-------------------+
|      Target       |           |      Adapter      |
|-------------------|           |-------------------|
| + request()       |<----------|>+ request()       |
+-------------------+           |-------------------|
                                  | + doSomething()   |
                                  |-------------------|
                                  +-------------------+
                                        ^
                                        |
                                        |
                                  +-------------------+
                                  |      Adaptee      |
                                  |-------------------|
                                  | + doSomething()   |
                                  +-------------------+

C++ 代码示例
#include <iostream>

// Target 接口
class Target {
public:
    virtual void request() const = 0;
};

// Adaptee 接口
class Adaptee {
public:
    virtual void doSomething() const = 0;
};

// 具体的 Adaptee 类
class ConcreteAdaptee : public Adaptee {
public:
    void doSomething() const override {
        std::cout << "ConcreteAdaptee: Doing something." << std::endl;
    }
};

// Adapter 类
class Adapter : public Target, public Adaptee {
private:
    ConcreteAdaptee* adaptee;

public:
    Adapter(ConcreteAdaptee* adaptee) : adaptee(adaptee) {}

    void request() const override {
        adaptee->doSomething();
    }

    void doSomething() const override {
        adaptee->doSomething();
    }
};

// 客户端代码
int main() {
    ConcreteAdaptee* adaptee = new ConcreteAdaptee();
    Adapter* adapter = new Adapter(adaptee);

    adapter->request(); // 调用适配器的方法
    adapter->doSomething(); // 调用 Adaptee 的方法

    delete adaptee;
    delete adapter;

    return 0;
}

总结

可插入适配器和Adaptee的窄接口是适配器模式的两个重要概念。通过对象适配器、类适配器和双适配器这三种实现方式,适配器可以灵活地适配不同的Adaptee对象,解决接口不兼容的问题。这些实现方式各有优缺点,选择哪种方式取决于具体的需求和设计考虑。

在窄接口实现中,可以通过抽象实现、使用代理对象和参数化适配器方式来实现适配器模式。下面分别说明这三种方式,并给出相应的UML图和C++代码示例。

1. 抽象实现(Abstract Implementation)

抽象实现通过定义一个抽象基类来提供Adaptee的窄接口,然后具体的Adaptee实现类从这个抽象基类继承。适配器类可以持有这个抽象基类的引用,从而在运行时适配不同的具体实现。

UML 类图
+-------------------+           +-------------------+           +-------------------+
|      Target       |           |      Adapter      |           |      Adaptee1     |
|-------------------|           |-------------------|           |-------------------|
| + request()       |<----------|>+ request()       |<----------|>+ doSomething()   |
+-------------------+           |-------------------|           +-------------------+
                                  | - adaptee: Adaptee|
                                  |-------------------|
                                  +-------------------+
                                        ^
                                        |
                                        |
                                  +-------------------+           +-------------------+
                                  |  AbstractAdaptee  |           |      Adaptee2     |
                                  |-------------------|           |-------------------|
                                  | + doSomething()   |<----------|>+ doSomething()   |
                                  +-------------------+           +-------------------+

C++ 代码示例
#include <iostream>

// Target 接口
class Target {
public:
    virtual void request() const = 0;
};

// 抽象的 Adaptee 基类
class AbstractAdaptee {
public:
    virtual void doSomething() const = 0;
};

// 具体的 Adaptee 实现类 1
class Adaptee1 : public AbstractAdaptee {
public:
    void doSomething() const override {
        std::cout << "Adaptee1: Doing something." << std::endl;
    }
};

// 具体的 Adaptee 实现类 2
class Adaptee2 : public AbstractAdaptee {
public:
    void doSomething() const override {
        std::cout << "Adaptee2: Doing something." << std::endl;
    }
};

// Adapter 类
class Adapter : public Target {
private:
    AbstractAdaptee* adaptee;

public:
    Adapter(AbstractAdaptee* adaptee) : adaptee(adaptee) {}

    void request() const override {
        adaptee->doSomething();
    }
};

// 客户端代码
int main() {
    AbstractAdaptee* adaptee1 = new Adaptee1();
    AbstractAdaptee* adaptee2 = new Adaptee2();

    Target* adapter1 = new Adapter(adaptee1);
    Target* adapter2 = new Adapter(adaptee2);

    adapter1->request(); // 调用适配器的方法
    adapter2->request(); // 调用适配器的方法

    delete adaptee1;
    delete adaptee2;
    delete adapter1;
    delete adapter2;

    return 0;
}

2. 使用代理对象(Proxy Object)

代理对象是通过创建一个代理类来间接访问Adaptee的方法。适配器类持有这个代理对象的引用,并通过代理对象来调用Adaptee的方法。这种方式可以提供额外的控制和功能,比如访问控制、缓存等。

UML 类图
+-------------------+           +-------------------+           +-------------------+
|      Target       |           |      Adapter      |           |      Proxy        |
|-------------------|           |-------------------|           |-------------------|
| + request()       |<----------|>+ request()       |<----------|>+ doSomething()   |
+-------------------+           |-------------------|           +-------------------+
                                  | - proxy: Proxy    |
                                  |-------------------|
                                  +-------------------+
                                        ^
                                        |
                                        |
                                  +-------------------+           +-------------------+
                                  |      Proxy        |           |      Adaptee      |
                                  |-------------------|           |-------------------|
                                  | + doSomething()   |<----------|>+ doSomething()   |
                                  +-------------------+           +-------------------+

C++ 代码示例
#include <iostream>

// Target 接口
class Target {
public:
    virtual void request() const = 0;
};

// Adaptee 类
class Adaptee {
public:
    void doSomething() const {
        std::cout << "Adaptee: Doing something." << std::endl;
    }
};

// Proxy 类
class Proxy {
private:
    Adaptee* adaptee;

public:
    Proxy(Adaptee* adaptee) : adaptee(adaptee) {}

    void doSomething() const {
        std::cout << "Proxy: Before calling Adaptee." << std::endl;
        adaptee->doSomething();
        std::cout << "Proxy: After calling Adaptee." << std::endl;
    }
};

// Adapter 类
class Adapter : public Target {
private:
    Proxy* proxy;

public:
    Adapter(Proxy* proxy) : proxy(proxy) {}

    void request() const override {
        proxy->doSomething();
    }
};

// 客户端代码
int main() {
    Adaptee* adaptee = new Adaptee();
    Proxy* proxy = new Proxy(adaptee);
    Target* adapter = new Adapter(proxy);

    adapter->request(); // 调用适配器的方法

    delete adaptee;
    delete proxy;
    delete adapter;

    return 0;
}

3. 参数化适配器(Parameterized Adapter)

参数化适配器通过将Adaptee的方法参数化,使得适配器可以在运行时传递不同的参数来调用Adaptee的方法。这种方式可以增强适配器的灵活性。

UML 类图
+-------------------+           +-------------------+
|      Target       |           |      Adapter      |
|-------------------|           |-------------------|
| + request()       |<----------|>+ request()       |
+-------------------+           |-------------------|
                                  | - adaptee: Adaptee|
                                  |-------------------|
                                  +-------------------+
                                        ^
                                        |
                                        |
                                  +-------------------+
                                  |      Adaptee      |
                                  |-------------------|
                                  | + doSomething(int)|
                                  +-------------------+

C++ 代码示例
#include <iostream>

// Target 接口
class Target {
public:
    virtual void request() const = 0;
};

// Adaptee 类
class Adaptee {
public:
    void doSomething(int param) const {
        std::cout << "Adaptee: Doing something with parameter " << param << "." << std::endl;
    }
};

// Adapter 类
class Adapter : public Target {
private:
    Adaptee* adaptee;
    int param;

public:
    Adapter(Adaptee* adaptee, int param) : adaptee(adaptee), param(param) {}

    void request() const override {
        adaptee->doSomething(param);
    }
};

// 客户端代码
int main() {
    Adaptee* adaptee = new Adaptee();
    Target* adapter = new Adapter(adaptee, 42);

    adapter->request(); // 调用适配器的方法

    delete adaptee;
    delete adapter;

    return 0;
}

总结

这三种方式都可以在窄接口实现中使用,根据具体的需求选择不同的实现方式。抽象实现提供了灵活的适配能力,代理对象提供了额外的控制和功能,参数化适配器增强了适配器的灵活性。每种方式都有其适用的场景,选择合适的方式可以提高代码的可维护性和扩展性。


http://www.kler.cn/a/408106.html

相关文章:

  • 4-SpringCloud整合服务间的调用即负载均衡
  • LSA1类和2类区别
  • 部署自动清理任务解决ORA-00257: archiver error. Connect internal only, until freed
  • 真实网络安全面试场景题
  • 摄影:相机控色
  • 使用 helm 部署 gitlab
  • 大模型(LLMs)推理篇
  • 前端开发调试之移动端调试学习笔记
  • 【自动化】如何从列表中找到图片并命名保存下来
  • 2061:【例1.2】梯形面积(http://ybt.ssoier.cn:8088/problem_show.php?pid=2061)
  • 科研实验室的数字化转型:Spring Boot系统
  • C# 命名空间详解(一)
  • 计算机网络socket编程(5)_TCP网络编程实现echo_server
  • C语言:操作符详解1
  • Java 腾讯云短信发送
  • github中banch和tag的应用
  • 【Mybatis】动态SQL详解
  • 金融服务的未来:测试自动化如何驱动合规、安全与创新
  • PHP实现选择排序
  • Rust宏系列教程—实现复杂派生宏
  • 以3D数字人AI产品赋能教育培训人才发展,魔珐科技亮相AI+教育创新与人才发展大会
  • 线程控制方法之wait和sleep的区别
  • 深入理解索引(二)
  • ubuntu搭建k8s环境详细教程
  • 「Mac玩转仓颉内测版28」基础篇8 - 元组类型详解
  • linux ollama安装没有sudo权限