自学内容网 自学内容网

C++ 【桥接模式】

简单介绍

桥接模式属于 结构型模式 | 可将一个大类或一系列紧密相关的类拆分 为抽象和实现两个独立的层次结构, 从而能在开发时分别使用。

聚合关系:两个类处于不同的层次,强调了一个整体/局部的关系,当汽车对象销毁时,轮胎对象也可以单独存在

public class 轮胎{  }
public class 汽车{
    protected:轮胎 tyre[4];
}

基础理解

Q:为什么要用桥接模式
A:使得抽象部分和实现部分分离,使它们可以独立地变化。且允许抽象部分和实现部分之间建立多对多的关系形成 聚合关系

Q:什么是抽象什么是实现
A:抽象 是一些实体的高阶控制层。抽象调用实现,实现来完成具体实现的工作

这里的形状就是抽象,与涂颜色(实现)形成聚合关系:抽象包含涂颜色
在这里插入图片描述

UML 图

解释:客户端只需要调用抽象部分。抽象部分与实现部分成为聚合关系。你可以详写一个精确的抽象,然后就可以在客户端用这个精确的抽象调用具体的实现。


空心箭头:继承关系
实线箭头:关联关系
棱形实线箭头:聚合关系
在这里插入图片描述

抽象部分和实现部分

在实际的程序中, 你可以在两个独立方向上扩展这种应用:

开发多个不同的 精确抽象 (例如:面向微信用户和支付宝用户 )
支持多个不同的 具体实现 (例如:能够使用 密码支付 人脸支付 和 指纹支付)。

  1. 抽象对象控制程序的外观
    (微信用户和支付宝用户抽象成用户,通过这些抽象对象,我们可以统一对支付进行管理和调用,而不需要关心具体的支付实现方式。)
  2. 并将真实工作委派给连入的实现对象
    (抽象类与实现类发生聚合关系,抽象类可以调用密码支付 人脸支付 和 指纹支付方式)
  3. 不同的实现只要遵循相同的接口就可以互换
    (只要遵循了相同的接口:PaymentMode 支付接口,就可以在程序中互换使用)
  4. 精确抽象(微信用户)就可以使用多个具体实现接口( 密码支付 人脸支付 和 指纹支付)

关键点:聚合关系,精确抽象类构造函数中对不同API 的调用

#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;

// 支付方式接口
class PaymentMode
{
public:
    virtual ~PaymentMode() {}
    virtual bool security(string uId) = 0;
};

// 具体支付方式实现类:密码支付
class PayByCypher : public PaymentMode
{
public:
    bool security(string uId) override
    {
        cout << "密码支付的安全检查" << endl;
        // 实现具体的安全验证逻辑
        return true;
}
}
;

// 具体支付方式实现类:人脸支付
class PayByFace : public PaymentMode
{
public:
    bool security(string uId) override
    {
        cout << "人脸支付的安全检查" << endl;
        // 实现具体的安全验证逻辑
        return true;
    }
};

// 具体支付方式实现类:指纹支付
class PayByFingerprint : public PaymentMode
{
public:
    bool security(string uId) override
    {
        cout << "指纹支付的安全检查" << endl;
        // 实现具体的安全验证逻辑
        return true;
    }
};

// 支付抽象类
class Payment
{
public:
    Payment(PaymentMode *mode_) : mode(mode_) {}
    virtual ~Payment() {}
    virtual void pay(string uId, string tradeId, long long amount) = 0;

protected:
    PaymentMode *mode;
};

// 扩展抽象化角色:微信支付
class WxPayment : public Payment
{
public:
    WxPayment(PaymentMode *mode) : Payment(mode) {}

    void pay(string uId, string tradeId, long long amount) override
    {
        cout << "使用微信支付" << endl;
        bool isSecure = mode->security(uId);
        if (isSecure)
        {
            cout << "微信支付成功,交易号:" << tradeId << ",金额:" << amount << endl;
        }
        else
        {
            cout << "微信支付失败,交易号:" << tradeId << ",金额:" << amount << endl;
        }
    }
};

// 扩展抽象化角色:支付宝支付
class AliPayment : public Payment
{
public:
    AliPayment(PaymentMode *mode) : Payment(mode) {}

    void pay(string uId, string tradeId, long long amount) override
    {
        cout << "支付宝支付开始" << endl;
        bool isSecure = mode->security(uId);
        if (isSecure)
        {
            cout << "支付宝支付成功,交易号:" << tradeId << ",金额:" << amount << endl;
        }
        else
        {
            cout << "支付宝支付失败,交易号:" << tradeId << ",金额:" << amount << endl;
        }
    }
};

int main()
{
    PaymentMode *cypherMode = new PayByCypher();
    PaymentMode *faceMode = new PayByFace();

    Payment *wxPayment = new WxPayment(cypherMode);
    Payment *aliPayment = new AliPayment(faceMode);

    wxPayment->pay("user123", "123456", 100);
    aliPayment->pay("user456", "789012", 200);

    delete cypherMode;
    delete faceMode;
    delete wxPayment;
    delete aliPayment;

    system("pause");
    return 0;
}

应用场景

如果你想要拆分或重组一个具有多重功能的庞杂类 (例如能与多个数据库服务器进行交互的类), 可以使用桥接模式。

桥接模式可以将庞杂类拆分为几个类层次结构。 此后, 你可以修改任意一个类层次结构而不会影响到其他类层次结构。 这种方法可以简化代码的维护工作, 并将修改已有代码的风险降到最低。

如果你需要在运行时切换不同实现方法, 可使用桥接模式。

当然并不是说一定要实现这一点, 桥接模式可替换抽象部分中的实现对象,只需要在抽象部分中引入实现对象,并通过接口进行交互。

顺便提一句, 最后一点是很多人混淆桥接模式和策略模式的主要原因。 记住, 设计模式并不仅是一种对类进行组织的方式, 它还能用于沟通意图和解决问题。
(在实现上有点像但是策略模式主要是针对算法,根据你的具体情况使用合适的策略算法)

与其他模式的关系

  1. 桥接、 状态模式和策略模式 (在某种程度上包括适配器) 模式的接口非常相似。 实际上, 它们都基于聚合模式——即将工作委派给其他对象, 不过也各自解决了不同的问题。 模式并不只是以特定方式组织代码的配方, 你还可以使用它们来和其他开发者讨论模式所解决的问题。
  2. 你可以结合使用生成器模式和桥接模式: 主管类(定义调用构造步骤的顺序)负责抽象工作, 各种不同的生成器(会生成具体的产品)负责实现工作。
  3. 桥接模式通常会于开发前期进行设计, 使你能够将程序的各个部分独立开来以便开发。 另一方面, 适配器(为各种接口进行兼容和匹配)模式通常在已有程序中使用, 让相互不兼容的类能很好地合作。

浅薄理解,如果有错还望指正。谢谢大家。


原文地址:https://blog.csdn.net/Absorbed__/article/details/137248791

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!