C++结构型模式-桥接模式

1.1 基本概念

桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。是一种对象结构模式。

将抽象与实现分离,使它们可以独立变化。它是用关联关系(组合或聚合关系)代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。

如何理解桥接: 像桥梁一样的,对象和对象像桥梁一样的连接。

如:形状-抽象类,颜色-抽象类,如何让他们像一个桥一样,产生关系?

形状拥有了颜色 这样产生了关系。

1.2 模式结构

(1)Abstraction(抽象类)

用于定义抽象类的接口,其中定义了一个Implementation(实现类接口)的对象并可以维护该对象,它与 Implementation具有关联关系。

(2)Refined Abstraction(扩充抽象类)

扩充由Abstraction定义的接口,通常它不再是抽象类而是具体类。提供控制逻辑的变体。与其父类一样,它们通过通用实现接口与不同的实现进行交互

提供高层控制逻辑,依赖于完成底层实际工作的实现对像
(3)Implementation(实现类接口)

为所有具体实现声明通用接口。抽象部分仅能通过在这里声明的方法与实现对象交互
(4)ConcreateImplementations(具体实现类)

包括特定的实现代码

(5)Client(客户端)

仅关心如何与抽象部分合作。但是,Client需要将抽象对象与一个实现对象连接起来。
 

1.3 优缺点

优点:

(1)分离抽象类及其实现部分。桥接模式使用“对象间的关联关系”解耦了抽象和实现之间 固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。

(2)桥接模式是比多继承方案更好的解决方法。

(3)桥接模式提高了系统的可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有的系统。

(4)实现细节对客户透明,可以对用户隐藏实现细节。用户在使用时不需要关系实现,在抽象层通过聚合关联关系完成封装与对象组合。

缺点:

(1)桥接模式的引入会增加系统的理解与设计难度。聚合关系建立在抽象层,要求开发者针对抽象进行设计与编程。

(2)桥接模式要求正确识别出系统的两个独立变化的维度,因此使用范围具有一定的局限性。

1.4 应用场景

当一个类内部具备两种或多种变化维度时,使用桥接模式可以解耦这些变化的维度,使高层代码架构稳定。
桥接模式通常适用于以下场景。

  1. 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。
  2. 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时。
  3. 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时

1.5 实例

如手机支付方式微信、支付宝APP,而每种APP支持三种付款验证方式,密码、指纹、人脸,则桥接模式的实现方式如下:

IPayMode类是实现类,定义了基本操作security(),用于设置验证方式,其子类提供了实现,它位于桥接模式的抽象层。

#include <iostream> 
using namespace std; 

// 实现类接口 Implementation(实现类接口):支付模式 
class IPayMode {
public:
    virtual bool security(string Uid) = 0;
};

// 具体实现类:密码支付
class PayCypher : public IPayMode {
public:
    bool security(string uId) override {
        cout << "Password to pay" << endl;
        return true;
    }
};

// 具体实现类:人脸支付
class PayFaceMode : public IPayMode {
public:
    bool security(string uId) override {
         cout << "Face to pay" << endl;
        return true;
    }
};

// 具体实现类:指纹支付
class PayFingerprintMode : public IPayMode {
public:
    bool security(string uId) override {
        cout << "fingo-pay" << endl;
        return true;
    }
};

// 抽象化类:支付
class Pay {
public:
    Pay(IPayMode* payMode) {
        this->payMode = payMode;//抽象类中定义了一个 IPayMode,与IPayMode存在关联关系
    }

    virtual ~Pay() { delete payMode; }

    virtual string transfer(string uId, string tradeId, long long amount) = 0;

    IPayMode* payMode;
};

// 扩展抽象化角色: 微信支付
class WxPay : public Pay {
public:
    WxPay(IPayMode* payMode) : Pay(payMode) { }
    //扩展抽象类 实现了抽象类中定义的方法
    string transfer(string uId, string tradeId, long long amount) {
         cout << "WeChat pay start, uId: " << uId << " tradeId: " 
             << tradeId << "amount: " << amount << endl;
        bool security = payMode->security(uId);
        if (!security) {
            cout << "WeChat pay failed, uId: " << uId << " tradeId: " 
             << tradeId << " amount: " << amount << endl;
             return "0001";
        }

        cout << "WeChat pay succeed, uId: " << uId << " tradeId: " 
             << tradeId << " amount: " << amount << endl;

        return "0000";
    }
};

// 扩展抽象化角色:支付宝支付
class ZfbPay : public Pay {
public:
    ZfbPay(IPayMode* payMode) : Pay(payMode) { }

    string transfer(string uId, string tradeId, long long amount) {
        cout << "Alipay pay start, uId: " << uId << " tradeId: " 
             << tradeId << " amount: " << amount << endl;
        bool security = payMode->security(uId);
        if (!security) {
            cout <<"Alipay pay failed,uId: " << uId << " tradeId: " 
             << tradeId << " amount: " << amount << endl;
             return "0001";
        }

        cout <<"Alipay pay succeed,uId: " << uId << " tradeId: " 
             << tradeId << " amount: " << amount << endl;

        return "0000";
    }
};

// 客户端使用
int main() {
    cout << "--------Please select the method of payment------------" << endl;
    Pay* wxPay = new WxPay(new PayFaceMode());
    wxPay->transfer("weixin_666", "a123456", 290);

    cout << endl;

    cout << "--------Please select the method of payment----------" << endl;
    Pay* zfbPay = new ZfbPay(new PayCypher());
    zfbPay->transfer("zfb_888, "a123456", 319);
}

--------Please select the method of payment------------
WeChat pay start, uId: weixin_666 tradeId: a123456amount: 290
Face to pay
WeChat pay succeed, uId: weixin_666 tradeId: a123456 amount: 290
--------Please select the method of payment----------
Alipay pay start, uId: zfb_888 tradeId: a123456 amount: 319
Password to pay
Alipay pay succeed,uId: zfb_888 tradeId: a123456 amount: 319
 

参考文献:

【1】C++ 桥接模式 - 岁月飞扬 - 博客园

【2】 https://www.jb51.net/article/80850.htm

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值