C++ 桥接模式

意图

将抽象部分与它的实现部分分离,使它们都可以独立地变化。

适用性

  • 你不希望在抽象和实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分应可以选择huoqieh
  • 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时 Bridge 模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充
  • 对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译
  • 有许多类要生成。这样一种类层次结构说明你必须将一个对象分解成两个部分
  • 你想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点

模式结构

  1. 抽象化角色:定义抽象类,并包含对一个对实现化对象的引用
  2. 扩展抽象化角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法
  3. 实现化角色:定义实现化角色的接口,供扩展抽象化角色调用
  4. 具体实现化角色:给出实现化角色接口的具体实现

示意性代码

// 实现化角色:支付模式
class IPayMode {
public:
    virtual bool security(string Uid) = 0;
};

// 具体实现化角色:密码支付
class PayCypher : public IPayMode {
public:
    bool security(string uId) override {
        cout << "密码支付,风控校验环境安全" << endl;
        return true;
    }
};

// 具体实现化角色:人脸支付
class PayFaceMode : public IPayMode {
public:
    bool security(string uId) override {
        cout << "人脸支付,风控校验脸部识别" << endl;
        return true;
    }
};

// 具体实现化角色:指纹支付
class PayFingerprintMode : public IPayMode {
public:
    bool security(string uId) override {
        cout << "指纹支付,风控检验指纹信息" << endl;
        return true;
    }
};

// 抽象化角色:支付
class Pay {
public:
    Pay(IPayMode* payMode) {
        this->payMode = payMode;
    }

    virtual ~Pay() { delete payMode; }

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

private:
    IPayMode* payMode;
};

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

    string transfer(string uId, string tradeId, long long amount) {
        cout << "模拟微信渠道支付划账开始,uId: " << uId << " tradeId: " 
             << tradeId << "amount: " << amount << endl;
        bool security = payMode->security(uId);
        if (!security) {
            cout << "模拟微信渠道支付划账拦截,uId: " << uId << " tradeId: " 
             << tradeId << " amount: " << amount << endl;
             return "0001";
        }

        cout << "模拟微信渠道支付划账成功,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 << "模拟支付宝渠道支付划账开始,uId: " << uId << " tradeId: " 
             << tradeId << " amount: " << amount << endl;
        bool security = payMode->security(uId);
        if (!security) {
            cout << "模拟支付宝渠道支付划账拦截,uId: " << uId << " tradeId: " 
             << tradeId << " amount: " << amount << endl;
             return "0001";
        }

        cout << "模拟支付宝渠道支付划账成功,uId: " << uId << " tradeId: " 
             << tradeId << " amount: " << amount << endl;

        return "0000";
    }
};

// 客户端使用
int main() {
    cout << "--------模拟测试场景:微信支付、人脸方式------------" << endl;
    Pay* wxPay = new WxPay(new PayFaceMode());
    wxPay->transfer("weixin_1024343434", "124243434", 243243);

    cout << endl;

    cout << "--------模拟测试场景:支付宝支付、指纹方式----------" << endl;
    Pay* zfbPay = new ZfbPay(new PayCypher());
    zfbPay->transfer("zfb_102434d3434", "12483838434", 233343);
}

img

参考

  1. 桥接模式(Bridge模式)详解
  2. 《重学Java设计模式》第10章:桥接模式
posted @ 2022-07-28 14:50  岁月飞扬  阅读(136)  评论(0编辑  收藏  举报