跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++Pay算法

C++ 设计模式实战:装饰者与适配器模式深度解析

装饰者模式与适配器模式是 C++ 结构型设计的核心。通过电商订单与支付网关案例,演示如何利用组合替代继承实现动态扩展与接口兼容。结合智能指针管理内存,提供完整可运行的代码示例,帮助开发者构建高内聚低耦合的系统架构。

虚拟内存发布于 2026/2/22更新于 2026/10/1587 浏览
C++ 设计模式实战:装饰者与适配器模式深度解析

C++ 设计模式实战:装饰者与适配器模式深度应用

学习目标与重点

本章旨在掌握装饰者模式的核心思想、角色划分及 C++ 实现细节,理解适配器模式的两种实现方式及其适用场景。通过结合实际业务场景(如功能增强、接口兼容),灵活运用两种模式解决类数量爆炸、接口不匹配等关键问题。

结构型模式的核心价值

在 C++ 开发中,结构型设计模式专注于解决'类与对象的组合方式'问题。相比行为型模式关注对象交互,结构型模式更侧重对象组装,通过合理的组合实现功能复用、接口兼容或功能扩展。

为什么需要结构型设计模式?

实际开发中常遇到以下结构相关的问题:

  • 需为一个对象动态添加额外功能(如给商品订单添加优惠券、积分抵扣),若使用继承会导致类数量爆炸;
  • 现有类的接口与目标接口不匹配(如第三方库的接口格式与项目现有接口不一致),直接使用会导致代码耦合严重;
  • 类的功能过于复杂,需拆分但又不想破坏原有接口;
  • 希望复用多个类的功能,但又不能通过多重继承实现(避免菱形继承、代码冗余)。

结构型模式通过标准化的组合方式,将核心功能与扩展功能分离,例如装饰者模式通过组合实现功能动态扩展,适配器模式通过转换实现接口兼容。

核心设计原则

结构型模式的设计始终围绕以下原则展开:

  1. 合成复用原则:优先使用对象组合,而非类继承,实现功能复用;
  2. 开放 - 封闭原则:扩展功能时无需修改原有代码,通过新增类实现;
  3. 接口隔离原则:适配或扩展时,不依赖不必要的接口,保持接口简洁;
  4. 依赖倒置原则:依赖抽象接口,不依赖具体实现。

装饰者模式:动态扩展对象功能的灵活方案

装饰者模式(Decorator Pattern)又称包装器模式,其核心思想是动态地给一个对象添加一些额外的职责,就像在墙上刷油漆一样,不改变对象本身的结构,却能增强其功能。

核心角色与设计逻辑

  • 抽象组件:定义被装饰对象和装饰者的共同接口,是装饰者模式的基础;
  • 具体组件:被装饰的核心对象,实现抽象组件接口,包含核心功能;
  • 抽象装饰者:继承自抽象组件,持有一个抽象组件的引用,定义装饰者的统一接口;
  • 具体装饰者:实现抽象装饰者接口,通过调用被装饰对象的方法,再添加额外功能。

抽象装饰者与具体组件继承自同一抽象组件,确保装饰者与被装饰者类型一致,可相互替换。抽象装饰者持有抽象组件的引用,通过组合方式将装饰者与被装饰者关联,实现嵌套结构,从而动态添加功能。

适用场景

  • 需动态为对象添加或移除功能(如订单支付时,根据用户选择动态添加优惠券、积分抵扣等);
  • 避免使用继承导致的类爆炸;
  • 扩展功能需灵活组合(如商品可以同时享受折扣 + 优惠券 + 满减多重优惠);
  • 不希望修改原有类的代码(符合开放 - 封闭原则)。

基础实现:电商订单优惠系统

以电商订单优惠系统为例:订单可享受多种优惠,且优惠可灵活组合。使用装饰者模式可动态扩展优惠功能。

步骤 1:定义抽象组件
#include <iostream>
#include <string>
#include <stdexcept>
using namespace std;

// 抽象组件:订单接口
class OrderComponent {
public:
    // 纯虚函数:计算最终价格
    virtual float CalculateFinalPrice() const = 0;
    // 纯虚函数:获取订单描述
    virtual string GetOrderDescription() const = 0;
    virtual ~OrderComponent() {}
};
步骤 2:实现具体组件(基础订单)
// 具体组件:基础订单(无任何优惠)
class BasicOrder : public OrderComponent {
private:
    string orderId;     // 订单 ID
    float originalPrice; // 商品原价

public:
    BasicOrder(const string& id, float price) : orderId(id), originalPrice(price) {
        if (price < 0) {
            throw invalid_argument("商品原价不能为负数!");
        }
    }

    // 计算最终价格(无优惠,返回原价)
    float CalculateFinalPrice() const override {
        return originalPrice;
    }

    // 获取订单描述
    string GetOrderDescription() const override {
        return "订单 [" + orderId + "] 基础价格:" + to_string(originalPrice) + "元";
    }

    // 获取原价(供装饰者使用)
    float GetOriginalPrice() const {
        return originalPrice;
    }
};
步骤 3:定义抽象装饰者
// 抽象装饰者:优惠装饰器
class DiscountDecorator : public OrderComponent {
private:
    // 持有抽象组件的引用(核心:组合方式关联被装饰对象)
    OrderComponent* component;

protected:
    // 保护方法:获取被装饰对象(供子类使用)
    OrderComponent* GetComponent() const { return component; }

public:
    // 构造函数:传入被装饰的订单组件
    DiscountDecorator(OrderComponent* comp) : component(comp) {
        if (comp == nullptr) {
            throw invalid_argument("被装饰的订单组件不能为空!");
        }
    }

    // 析构函数:不负责销毁被装饰对象(由客户端管理)
    ~DiscountDecorator() {}

    // 转发计算价格的调用(子类可扩展)
    float CalculateFinalPrice() const override {
        return component->CalculateFinalPrice();
    }

    // 转发订单描述的调用(子类可扩展)
    string GetOrderDescription() const override {
        return component->GetOrderDescription();
    }
};
步骤 4:实现具体装饰者(各种优惠)
// 具体装饰者 1:优惠券抵扣(固定金额抵扣)
class CouponDecorator : public DiscountDecorator {
private:
    float couponAmount; // 优惠券金额

public:
    CouponDecorator(OrderComponent* comp, float amount) : DiscountDecorator(comp), couponAmount(amount) {
        if (amount <= 0) {
            throw invalid_argument("优惠券金额必须大于 0!");
        }
    }

    // 计算最终价格:基础价格 - 优惠券金额(最低为 0)
    float CalculateFinalPrice() const override {
        float basePrice = GetComponent()->CalculateFinalPrice();
        float finalPrice = basePrice - couponAmount;
        return finalPrice < 0 ? 0 : finalPrice;
    }

    // 扩展订单描述:添加优惠券信息
    string GetOrderDescription() const override {
        return GetComponent()->GetOrderDescription() + " + 优惠券抵扣" + to_string(couponAmount) + "元";
    }
};

// 具体装饰者 2:积分抵扣(100 积分抵扣 1 元)
class PointsDecorator : public DiscountDecorator {
private:
    int points; // 抵扣积分

public:
    PointsDecorator(OrderComponent* comp, int pts) : DiscountDecorator(comp), points(pts) {
        if (pts <= 0) {
            throw invalid_argument("抵扣积分必须大于 0!");
        }
    }

    // 计算最终价格:基础价格 - 积分抵扣金额(积分/100)
    float CalculateFinalPrice() const override {
        float basePrice = GetComponent()->CalculateFinalPrice();
        float discountAmount = points / 100.0f; // 100 积分=1 元
        float finalPrice = basePrice - discountAmount;
        return finalPrice < 0 ? 0 : finalPrice;
    }

    string GetOrderDescription() const override {
        return GetComponent()->GetOrderDescription() + " + " + to_string(points) + "积分抵扣" + to_string(points / 100.0f) + "元";
    }
};

// 具体装饰者 3:满减优惠(满 X 减 Y)
class FullReduceDecorator : public DiscountDecorator {
private:
    float fullAmount; // 满减门槛
    float reduceAmount; // 减免金额

public:
    FullReduceDecorator(OrderComponent* comp, float full, float reduce) : DiscountDecorator(comp), fullAmount(full), reduceAmount(reduce) {
        if (full <= 0 || reduce <= 0) {
            throw invalid_argument("满减门槛和减免金额必须大于 0!");
        }
        if (reduce >= full) {
            throw invalid_argument("减免金额不能大于等于满减门槛!");
        }
    }

    // 计算最终价格:满足门槛则减免
    float CalculateFinalPrice() const override {
        float basePrice = GetComponent()->CalculateFinalPrice();
        float finalPrice = basePrice;
        if (basePrice >= fullAmount) {
            finalPrice = basePrice - reduceAmount;
        }
        return finalPrice < 0 ? 0 : finalPrice;
    }

    string GetOrderDescription() const override {
        return GetComponent()->GetOrderDescription() + " + 满" + to_string(fullAmount) + "减" + to_string(reduceAmount) + "元";
    }
};
步骤 5:客户端使用示例
int main() {
    try {
        // 1. 创建基础订单(原价 1500 元)
        OrderComponent* basicOrder = new BasicOrder("ORD20240502001", 1500.0f);
        cout << "=== 基础订单 ===" << endl;
        cout << basicOrder->GetOrderDescription() << endl;
        cout << "最终价格:" << basicOrder->CalculateFinalPrice() << "元" << endl;

        // 2. 仅使用优惠券(抵扣 200 元)
        OrderComponent* couponOrder = new CouponDecorator(basicOrder, 200.0f);
        cout << "\n=== 基础订单 + 优惠券 ===" << endl;
        cout << couponOrder->GetOrderDescription() << endl;
        cout << "最终价格:" << couponOrder->CalculateFinalPrice() << "元" << endl;

        // 3. 优惠券 + 积分抵扣(500 积分=5 元)
        OrderComponent* couponPointsOrder = new PointsDecorator(couponOrder, 500);
        cout << "\n=== 基础订单 + 优惠券 + 积分 ===" << endl;
        cout << couponPointsOrder->GetOrderDescription() << endl;
        cout << "最终价格:" << couponPointsOrder->CalculateFinalPrice() << "元" << endl;

        // 4. 优惠券 + 积分 + 满 1000 减 150
        OrderComponent* fullReduceOrder = new FullReduceDecorator(couponPointsOrder, 1000.0f, 150.0f);
        cout << "\n=== 基础订单 + 优惠券 + 积分 + 满减 ===" << endl;
        cout << fullReduceOrder->GetOrderDescription() << endl;
        cout << "最终价格:" << fullReduceOrder->CalculateFinalPrice() << "元" << endl;

        // 5. 另一种组合:基础订单 + 满减(单独使用满减)
        OrderComponent* onlyFullReduceOrder = new FullReduceDecorator(basicOrder, 1000.0f, 150.0f);
        cout << "\n=== 基础订单 + 满减 ===" << endl;
        cout << onlyFullReduceOrder->GetOrderDescription() << endl;
        cout << "最终价格:" << onlyFullReduceOrder->CalculateFinalPrice() << "元" << endl;

        // 6. 释放资源(注意:装饰者不负责销毁被装饰对象,需手动按层级释放)
        delete fullReduceOrder;
        delete couponPointsOrder;
        delete couponOrder;
        delete onlyFullReduceOrder;
        delete basicOrder;
    } catch (const exception& e) {
        cout << "错误:" << e.what() << endl;
    }
    return 0;
}

进阶优化:智能指针管理与多层装饰增强

基础实现中,手动管理装饰者层级的内存容易出错。以下优化方案使用智能指针自动管理内存,并新增限时折扣装饰者。

优化 1:使用智能指针管理内存
#include <memory>

int main() {
    try {
        // 使用 shared_ptr 自动管理内存,无需手动释放
        shared_ptr<OrderComponent> basicOrder = make_shared<BasicOrder>("ORD20240502002", 2000.0f);

        // 组合优惠:优惠券(300 元)+ 限时折扣(9 折)+ 满 1500 减 200
        shared_ptr<OrderComponent> couponOrder = make_shared<CouponDecorator>(basicOrder.get(), 300.0f);
        shared_ptr<OrderComponent> discountOrder = make_shared<DiscountDecorator>(couponOrder.get(), [](float basePrice) { return basePrice * 0.9f; });
        shared_ptr<OrderComponent> fullReduceOrder = make_shared<FullReduceDecorator>(discountOrder.get(), 1500.0f, 200.0f);

        cout << "=== 智能指针管理:多层优惠组合 ===" << endl;
        cout << fullReduceOrder->GetOrderDescription() << endl;
        cout << "最终价格:" << fullReduceOrder->CalculateFinalPrice() << "元" << endl;
        // 智能指针自动析构,无需手动 delete
    } catch (const exception& e) {
        cout << "错误:" << e.what() << endl;
    }
    return 0;
}
优化 2:新增限时折扣装饰者
// 具体装饰者 4:限时折扣(支持动态设置折扣率)
class TimeLimitDiscountDecorator : public DiscountDecorator {
private:
    float discountRate; // 折扣率(如 0.9 表示 9 折)

public:
    TimeLimitDiscountDecorator(OrderComponent* comp, float rate) : DiscountDecorator(comp), discountRate(rate) {
        if (rate <= 0 || rate >= 1) {
            throw invalid_argument("折扣率必须在 (0,1) 之间!");
        }
    }

    // 计算最终价格:基础价格 * 折扣率
    float CalculateFinalPrice() const override {
        float basePrice = GetComponent()->CalculateFinalPrice();
        return basePrice * discountRate;
    }

    string GetOrderDescription() const override {
        return GetComponent()->GetOrderDescription() + " + 限时" + to_string(discountRate * 10) + "折";
    }

    // 动态修改折扣率(扩展功能)
    void SetDiscountRate(float rate) {
        if (rate <= 0 || rate >= 1) {
            throw invalid_argument("折扣率必须在 (0,1) 之间!");
        }
        discountRate = rate;
    }
};

// 客户端测试动态折扣
int main() {
    shared_ptr<OrderComponent> basicOrder = make_shared<BasicOrder>("ORD20240502003", 1000.0f);
    shared_ptr<TimeLimitDiscountDecorator> timeLimitOrder = make_shared<TimeLimitDiscountDecorator>(basicOrder.get(), 0.9f);

    cout << "=== 限时折扣测试 ===" << endl;
    cout << timeLimitOrder->GetOrderDescription() << endl;
    cout << "9 折后价格:" << timeLimitOrder->CalculateFinalPrice() << "元" << endl;

    // 动态修改为 8 折
    timeLimitOrder->SetDiscountRate(0.8f);
    cout << "\n修改为 8 折后:" << endl;
    cout << timeLimitOrder->GetOrderDescription() << endl;
    cout << "8 折后价格:" << timeLimitOrder->CalculateFinalPrice() << "元" << endl;
    return 0;
}

优缺点与避坑指南

优点

  • 动态扩展功能:无需修改原有代码,通过新增装饰者即可扩展功能;
  • 功能组合灵活:多个装饰者可嵌套组合,实现复杂功能;
  • 替代继承减少类爆炸:避免为每个功能组合创建单独的子类;
  • 保持接口一致性:装饰者与被装饰者继承自同一抽象接口,可无缝替换。

缺点

  • 层级嵌套复杂:多层装饰者嵌套后,调试和理解难度增加;
  • 内存管理复杂:手动管理时需按层级释放资源,容易出现内存泄漏;
  • 仅适用于同一抽象接口:装饰者与被装饰者必须依赖同一抽象组件。

避坑指南

  • 使用智能指针管理内存:优先使用 shared_ptr 自动管理生命周期;
  • 控制装饰者层级:避免过度嵌套(建议不超过 3 层);
  • 明确装饰顺序:不同装饰顺序可能导致结果不同,需在业务中明确规则;
  • 抽象组件接口简洁:只定义核心接口,降低实现成本。

适配器模式:接口兼容的桥梁方案

适配器模式的核心思想是将一个类的接口转换成客户希望的另一个接口,使原本由于接口不兼容而不能一起工作的那些类可以一起工作。

核心角色与实现方式

  • 目标接口:客户期望的接口,适配器将其他接口转换为该接口;
  • 适配者:现有需要适配的接口(如第三方库接口、旧系统接口);
  • 适配器:实现目标接口,同时持有适配者的引用(或继承适配者),将目标接口的调用转换为适配者接口的调用。

两种实现方式

  • 类适配器:适配器继承自适配者和目标接口(多重继承),通过继承获取适配者的功能;
  • 对象适配器:适配器实现目标接口,同时持有适配者的对象引用(组合方式),通过委托调用适配者的功能。

实战建议:C++ 中优先使用对象适配器,避免多重继承带来的菱形继承、二义性等问题,且组合方式更灵活。

适用场景

  • 集成第三方库:第三方库的接口与项目现有接口不匹配;
  • 旧系统改造:旧系统的接口无法修改,但新系统需要使用其功能;
  • 接口标准化:多个类的功能相同但接口不同,需统一为目标接口;
  • 复用现有类:现有类功能满足需求,但接口不符合客户端要求。

实现方式 1:对象适配器(推荐)

以第三方支付接口适配为例:项目现有支付接口要求 Pay(float amount) 方法,而引入的第三方支付库的接口为 DoPayment(float money, string orderId),使用对象适配器将第三方接口转换为项目所需接口。

步骤 1:定义目标接口
#include <iostream>
#include <string>
using namespace std;

// 目标接口:项目现有支付接口
class PaymentTarget {
public:
    virtual bool Pay(float amount) = 0;      // 客户期望的接口:支付指定金额
    virtual string GetPaymentName() const = 0; // 获取支付方式名称
    virtual ~PaymentTarget() {}
};
步骤 2:定义适配者
// 适配者:第三方支付库(接口与目标接口不兼容)
class ThirdPartyPayment {
public:
    // 第三方接口:支付金额 + 订单 ID,返回是否成功
    bool DoPayment(float money, const string& orderId) {
        cout << "第三方支付库执行支付:订单 ID=" << orderId << ",金额=" << money << "元" << endl;
        return true;
    }

    // 第三方额外功能:查询支付状态
    string QueryPaymentStatus(const string& orderId) {
        return "订单" + orderId + "支付成功";
    }
};
步骤 3:实现对象适配器
// 对象适配器:将第三方支付接口转换为目标接口
class PaymentAdapter : public PaymentTarget {
private:
    ThirdPartyPayment* adaptee; // 持有适配者的引用(组合方式)
    string orderId;             // 订单 ID(适配时需要)

public:
    // 构造函数:传入适配者和订单 ID
    PaymentAdapter(ThirdPartyPayment* adapteeObj, const string& id) : adaptee(adapteeObj), orderId(id) {
        if (adapteeObj == nullptr) {
            throw invalid_argument("适配者对象不能为空!");
        }
    }

    ~PaymentAdapter() {
        // 适配器不负责销毁适配者(由客户端管理)
    }

    // 实现目标接口:将 Pay 调用转换为 DoPayment 调用
    bool Pay(float amount) override {
        if (amount <= 0) {
            cout << "支付金额必须大于 0!" << endl;
            return false;
        }
        return adaptee->DoPayment(amount, orderId);
    }

    string GetPaymentName() const override {
        return "第三方支付(适配器转换)";
    }

    // 扩展功能:通过适配器调用适配者的额外方法
    string QueryStatus() {
        return adaptee->QueryPaymentStatus(orderId);
    }
};
步骤 4:客户端使用示例
void ProcessPayment(PaymentTarget* payment, float amount) {
    cout << "=== 执行支付 ===" << endl;
    cout << "支付方式:" << payment->GetPaymentName() << endl;
    bool success = payment->Pay(amount);
    if (success) {
        cout << "支付成功!" << endl;
    } else {
        cout << "支付失败!" << endl;
    }
}

int main() {
    try {
        // 1. 创建适配者(第三方支付库)
        ThirdPartyPayment* thirdPartyPay = new ThirdPartyPayment();
        // 2. 创建适配器(传入适配者和订单 ID)
        PaymentAdapter* adapter = new PaymentAdapter(thirdPartyPay, "ORD20240503001");
        // 3. 客户端通过目标接口调用(无需知道第三方接口细节)
        ProcessPayment(adapter, 899.0f);
        // 4. 调用适配器扩展的查询功能
        cout << "\n查询支付状态:" << adapter->QueryStatus() << endl;
        // 5. 释放资源
        delete adapter;
        delete thirdPartyPay;
    } catch (const exception& e) {
        cout << "错误:" << e.what() << endl;
    }
    return 0;
}

实现方式 2:类适配器(多重继承)

同样以第三方支付接口适配为例,使用类适配器实现(继承适配者和目标接口):

// 类适配器:继承适配者和目标接口(多重继承)
class PaymentClassAdapter : public PaymentTarget, public ThirdPartyPayment {
private:
    string orderId;

public:
    PaymentClassAdapter(const string& id) : orderId(id) {}

    // 实现目标接口:调用父类(适配者)的 DoPayment 方法
    bool Pay(float amount) override {
        if (amount <= 0) {
            cout << "支付金额必须大于 0!" << endl;
            return false;
        }
        return DoPayment(amount, orderId);
    }

    string GetPaymentName() const override {
        return "第三方支付(类适配器)";
    }

    // 扩展功能:调用继承的 QueryPaymentStatus 方法
    string QueryStatus() {
        return QueryPaymentStatus(orderId);
    }
};

int main() {
    PaymentClassAdapter* classAdapter = new PaymentClassAdapter("ORD20240503002");
    ProcessPayment(classAdapter, 1299.0f);
    cout << "\n查询支付状态:" << classAdapter->QueryStatus() << endl;
    delete classAdapter;
    return 0;
}

两种适配器实现的对比

对比维度类适配器对象适配器
实现方式多重继承(目标接口 + 适配者)组合(实现目标接口 + 持有适配者引用)
灵活性差:只能适配特定适配者,无法适配其子类好:可适配适配者及其子类,支持多个适配者
耦合度高:与适配者类强耦合低:与适配者接口弱耦合
扩展能力差:新增适配者需修改或新增适配器好:可通过构造函数传入不同适配者
访问适配者方法直接访问(继承)间接访问(委托)
适用场景适配者类稳定,无子类扩展适配者可能有子类,需灵活适配

实战结论:对象适配器在灵活性、低耦合度上优势明显,是 C++ 开发中的首选方案;类适配器仅适用于适配者类稳定、无扩展需求的简单场景。

优缺点与避坑指南

优点

  • 解决接口不兼容问题:使原本无法协作的类可以一起工作;
  • 复用现有功能:无需修改现有类(适配者)的代码,直接复用其功能;
  • 透明性:客户端只依赖目标接口,无需知道适配者的存在,降低代码耦合;
  • 灵活性高:对象适配器支持适配多个适配者,可动态切换适配者。

缺点

  • 增加系统复杂度:新增适配器类会增加代码量,降低系统可读性;
  • 适配逻辑复杂:若目标接口与适配者接口差异较大,适配器的转换逻辑会非常复杂;
  • 性能损耗:适配器的委托调用会带来轻微的性能损耗(可忽略不计)。

避坑指南

  • 明确适配边界:适配器只负责接口转换,不添加额外业务逻辑;
  • 避免过度适配:若目标接口与适配者接口差异过大,应考虑重构接口;
  • 优先适配接口而非实现:适配器依赖适配者的接口,而非具体实现;
  • 结合工厂模式:使用工厂模式创建适配器,提升代码可维护性。

实战案例:结合装饰者模式与适配器模式开发支付网关系统

需求分析

开发一个统一支付网关系统,核心需求如下:

  1. 支持多种支付方式(微信支付、支付宝支付、第三方支付库),且支付接口统一;
  2. 支付过程需动态添加额外功能(如日志记录、签名验证、支付结果回调);
  3. 第三方支付库的接口与统一接口不兼容,需适配后使用;
  4. 支持支付方式和额外功能的灵活扩展;
  5. 客户端只需调用统一接口,无需关心具体支付方式和扩展功能的实现。

设计思路

  • 适配器模式:将第三方支付库、微信支付、支付宝支付的接口适配为统一支付接口;
  • 装饰者模式:为统一支付接口动态添加日志记录、签名验证、回调通知等扩展功能;
  • 组合设计:适配器封装具体支付方式的接口,装饰者包裹适配器(或基础支付类),实现'接口统一 + 功能扩展'的双重目标。

完整实现代码

#include <iostream>
#include <string>
#include <memory>
#include <ctime>
using namespace std;

// -------------------------- 部分 1:目标接口与基础支付类 --------------------------
// 目标接口:统一支付接口
class PaymentTarget {
public:
    virtual bool Pay(float amount) = 0;
    virtual string GetPaymentName() const = 0;
    virtual ~PaymentTarget() {}
};

// 基础支付类 1:微信支付(已符合目标接口,无需适配)
class WeChatPayment : public PaymentTarget {
public:
    bool Pay(float amount) override {
        cout << "[微信支付] 发起支付请求,金额:" << amount << "元" << endl;
        return true;
    }
    string GetPaymentName() const override {
        return "微信支付";
    }
};

// 基础支付类 2:支付宝支付(已符合目标接口,无需适配)
class AlipayPayment : public PaymentTarget {
public:
    bool Pay(float amount) override {
        cout << "[支付宝支付] 发起支付请求,金额:" << amount << "元" << endl;
        return true;
    }
    string GetPaymentName() const override {
        return "支付宝支付";
    }
};

// -------------------------- 部分 2:适配器模式 - 第三方支付适配 --------------------------
// 适配者:第三方支付库(接口不兼容)
class ThirdPartyPayLib {
public:
    bool ExecutePay(const string& orderNo, double money, const string& token) {
        cout << "[第三方支付库] 订单号:" << orderNo << ",金额:" << money << "元,token:" << token << endl;
        return true;
    }
    string GetPayResult(const string& orderNo) {
        return "第三方支付成功,订单号:" + orderNo;
    }
};

// 对象适配器:第三方支付适配为统一接口
class ThirdPartyPayAdapter : public PaymentTarget {
private:
    shared_ptr<ThirdPartyPayLib> adaptee;
    string orderNo;
    string token;

public:
    ThirdPartyPayAdapter(const string& no, const string& tk) : orderNo(no), token(tk) {
        adaptee = make_shared<ThirdPartyPayLib>();
    }

    bool Pay(float amount) override {
        if (amount <= 0) return false;
        return adaptee->ExecutePay(orderNo, amount, token);
    }

    string GetPaymentName() const override {
        return "第三方支付(适配器)";
    }

    string QueryPayResult() {
        return adaptee->GetPayResult(orderNo);
    }
};

// -------------------------- 部分 3:装饰者模式 - 支付功能扩展 --------------------------
// 抽象装饰者:支付功能装饰器
class PaymentDecorator : public PaymentTarget {
private:
    shared_ptr<PaymentTarget> component;

protected:
    shared_ptr<PaymentTarget> GetComponent() const {
        return component;
    }

public:
    PaymentDecorator(shared_ptr<PaymentTarget> comp) : component(comp) {
        if (!component) throw invalid_argument("支付组件不能为空!");
    }

    bool Pay(float amount) override {
        return component->Pay(amount);
    }

    string GetPaymentName() const override {
        return component->GetPaymentName();
    }
};

// 具体装饰者 1:日志记录装饰器
class LogPaymentDecorator : public PaymentDecorator {
public:
    LogPaymentDecorator(shared_ptr<PaymentTarget> comp) : PaymentDecorator(comp) {}

    bool Pay(float amount) override {
        time_t now = time(nullptr);
        cout << "[支付日志] " << ctime(&now) << " 开始支付,方式:" << GetComponent()->GetPaymentName() << ",金额:" << amount << "元" << endl;
        bool success = GetComponent()->Pay(amount);
        cout << "[支付日志] 支付结果:" << (success ? "成功" : "失败") << endl;
        return success;
    }

    string GetPaymentName() const override {
        return GetComponent()->GetPaymentName() + "(带日志)";
    }
};

// 具体装饰者 2:签名验证装饰器
class SignaturePaymentDecorator : public PaymentDecorator {
private:
    string appSecret;

public:
    SignaturePaymentDecorator(shared_ptr<PaymentTarget> comp, const string& secret) : PaymentDecorator(comp), appSecret(secret) {}

    bool Pay(float amount) override {
        cout << "[签名验证] 正在验证签名,appSecret:" << appSecret << endl;
        bool verifySuccess = true;
        if (!verifySuccess) {
            cout << "[签名验证] 签名失败,支付终止!" << endl;
            return false;
        }
        cout << "[签名验证] 签名成功,继续支付..." << endl;
        return GetComponent()->Pay(amount);
    }

    string GetPaymentName() const override {
        return GetComponent()->GetPaymentName() + "(带签名验证)";
    }
};

// 具体装饰者 3:回调通知装饰器
class CallbackPaymentDecorator : public PaymentDecorator {
private:
    string callbackUrl;

public:
    CallbackPaymentDecorator(shared_ptr<PaymentTarget> comp, const string& url) : PaymentDecorator(comp), callbackUrl(url) {}

    bool Pay(float amount) override {
        bool success = GetComponent()->Pay(amount);
        if (success) {
            cout << "[回调通知] 向" << callbackUrl << "发送支付成功回调" << endl;
        } else {
            cout << "[回调通知] 向" << callbackUrl << "发送支付失败回调" << endl;
        }
        return success;
    }

    string GetPaymentName() const override {
        return GetComponent()->GetPaymentName() + "(带回调)";
    }
};

// -------------------------- 部分 4:客户端测试与系统整合 --------------------------
class PaymentGateway {
public:
    static bool ProcessPayment(shared_ptr<PaymentTarget> payment, float amount) {
        cout << "\n==================== 支付网关 ====================" << endl;
        cout << "支付方式:" << payment->GetPaymentName() << endl;
        cout << "支付金额:" << amount << "元" << endl;
        bool success = payment->Pay(amount);
        cout << "==================================================" << endl;
        return success;
    }
};

int main() {
    try {
        // 1. 微信支付 + 日志 + 签名验证 + 回调
        shared_ptr<PaymentTarget> wechatPay = make_shared<WeChatPayment>();
        wechatPay = make_shared<LogPaymentDecorator>(wechatPay);
        wechatPay = make_shared<SignaturePaymentDecorator>(wechatPay, "wechat_secret_123");
        wechatPay = make_shared<CallbackPaymentDecorator>(wechatPay, "https://api.example.com/wechat/callback");
        PaymentGateway::ProcessPayment(wechatPay, 699.0f);

        // 2. 第三方支付(适配器)+ 日志 + 回调
        shared_ptr<PaymentTarget> thirdPartyPay = make_shared<ThirdPartyPayAdapter>("ORDER_20240504_001", "token_abc123");
        thirdPartyPay = make_shared<LogPaymentDecorator>(thirdPartyPay);
        thirdPartyPay = make_shared<CallbackPaymentDecorator>(thirdPartyPay, "https://api.example.com/thirdparty/callback");
        PaymentGateway::ProcessPayment(thirdPartyPay, 1599.0f);

        // 3. 支付宝支付(无扩展功能)
        shared_ptr<PaymentTarget> alipay = make_shared<AlipayPayment>();
        PaymentGateway::ProcessPayment(alipay, 399.0f);

        // 4. 扩展:新增银联支付
        class UnionPayPayment : public PaymentTarget {
        public:
            bool Pay(float amount) override {
                cout << "[银联支付] 发起支付请求,金额:" << amount << "元" << endl;
                return true;
            }
            string GetPaymentName() const override {
                return "银联支付";
            }
        };
        shared_ptr<PaymentTarget> unionPay = make_shared<UnionPayPayment>();
        unionPay = make_shared<LogPaymentDecorator>(unionPay);
        PaymentGateway::ProcessPayment(unionPay, 899.0f);
    } catch (const exception& e) {
        cout << "支付网关错误:" << e.what() << endl;
    }
    return 0;
}

运行效果

==================== 支付网关 ====================
支付方式:微信支付(带日志)(带签名验证)(带回调)
支付金额:699 元
[支付日志] Wed May 4 10:00:00 2024 开始支付,方式:微信支付(带签名验证)(带回调),金额:699 元
[签名验证] 正在验证签名,appSecret:wechat_secret_123
[签名验证] 签名成功,继续支付...
[微信支付] 发起支付请求,金额:699 元
[回调通知] 向 https://api.example.com/wechat/callback 发送支付成功回调
[支付日志] 支付结果:成功
==================================================

本章总结

本章重点讲解了 C++ 开发中常用的两种结构型设计模式:装饰者模式和适配器模式。

  1. 装饰者模式:核心价值在于动态扩展对象功能,避免继承导致的类爆炸。关键实现是抽象组件定义统一接口,抽象装饰者持有组件引用,具体装饰者添加额外功能。适用场景包括动态添加/移除功能、功能组合多样、不修改原有代码扩展功能。
  2. 适配器模式:核心价值是解决接口不兼容问题,使不同接口的类可以协同工作。两种实现中,对象适配器(组合方式)因灵活性和低耦合度成为首选,类适配器(多重继承)仅适用于简单场景。适用场景包括集成第三方库、旧系统改造、接口标准化。
  3. 模式组合技巧:装饰者 + 适配器可实现接口统一 + 功能扩展;装饰者 + 工厂模式可简化客户端使用;适配器 + 策略模式可动态切换算法。
  4. 实战注意事项:装饰者模式需控制层级、使用智能指针管理内存;适配器模式应避免过度适配、只负责接口转换;通用原则是优先组合而非继承、符合开放 - 封闭原则。

通过本章学习,应能熟练运用这两种模式解决实际开发中的功能扩展和接口兼容问题,编写灵活、可扩展、低耦合的 C++ 代码。后续章节将继续讲解其他结构型设计模式,进一步完善知识体系。

目录

  1. C++ 设计模式实战:装饰者与适配器模式深度应用
  2. 学习目标与重点
  3. 结构型模式的核心价值
  4. 为什么需要结构型设计模式?
  5. 核心设计原则
  6. 装饰者模式:动态扩展对象功能的灵活方案
  7. 核心角色与设计逻辑
  8. 适用场景
  9. 基础实现:电商订单优惠系统
  10. 步骤 1:定义抽象组件
  11. 步骤 2:实现具体组件(基础订单)
  12. 步骤 3:定义抽象装饰者
  13. 步骤 4:实现具体装饰者(各种优惠)
  14. 步骤 5:客户端使用示例
  15. 进阶优化:智能指针管理与多层装饰增强
  16. 优化 1:使用智能指针管理内存
  17. 优化 2:新增限时折扣装饰者
  18. 优缺点与避坑指南
  19. 适配器模式:接口兼容的桥梁方案
  20. 核心角色与实现方式
  21. 适用场景
  22. 实现方式 1:对象适配器(推荐)
  23. 步骤 1:定义目标接口
  24. 步骤 2:定义适配者
  25. 步骤 3:实现对象适配器
  26. 步骤 4:客户端使用示例
  27. 实现方式 2:类适配器(多重继承)
  28. 两种适配器实现的对比
  29. 优缺点与避坑指南
  30. 实战案例:结合装饰者模式与适配器模式开发支付网关系统
  31. 需求分析
  32. 设计思路
  33. 完整实现代码
  34. 运行效果
  35. 本章总结

更多推荐文章

查看全部
  • 大模型微调的核心三要素:算法、数据与算力
  • Windows 下 VSCode 配置 C/C++ 开发环境指南
  • 通义灵码 AI 程序员实操:IDE 安装与全栈需求落地
  • Linux 集群时间同步详解(NTP + Cron 配置方案)
  • Docker 核心概念:镜像、容器与 Dockerfile 详解
  • Python 列表与元组的区别及常用操作
  • Vivado 入门教程:工程创建、仿真与烧录流程
  • C 语言快速排序详解:从基础到非递归实现
  • Android 项目开发整体架构设计与演进
  • WebSphere 应用服务器节点同步异常排查与修复方案
  • Java JDK 安装与环境配置教程
  • 近端策略优化算法 PPO 详解与代码实现
  • 使用 Trae 构建本地 AI 对话机器人
  • React K 线图组件与股票数据 SDK 实现方案
  • 【VSCode Copilot登录失败终极指南】:9大常见问题与高效解决方案
  • AI 艺术二维码制作教程:使用 Stable Diffusion 生成可扫描创意图像
  • C++ 内存管理进阶:从裸指针到智能指针
  • Python 数据可视化入门教程
  • Linux 上通过 Docker 快速部署 Dify
  • FANUC 机器人 PR 寄存器完全解析

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online