目录

单一职责_Bridge


组件协作模式

在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码, 这时候的关键是划清责任。 典型模式: Decorator, Bridge

1 Bridge 桥接模式

1.1 模式动机

由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度, 乃至多个纬度的变化。

如何应对这种“多维度的变化“?如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度?

1.2 模式定义

将抽象部分(业务功能)与实现部分(平台实现)分离,使它们都可以独立地变化。

1.3 模式示例代码

# include <iostream>
# include <string>

// 定义电视的抽象类
class TV {
protected:
    std::string name;

public:
    TV(const std::string& name) : name(name) {}

    virtual void powerOn() = 0;
    virtual void powerOff() = 0;
    virtual void setChannel(int channel) = 0;
    virtual void adjustVolume(int volume) = 0;
};

// 具体电视类:Sony电视
class SonyTV : public TV {
public:
    SonyTV() : TV("Sony TV") {}

    void powerOn() {
        std::cout << name << ": 开机" << std::endl;
    }

    void powerOff() {
        std::cout << name << ": 关机" << std::endl;
    }

    void setChannel(int channel) {
        std::cout << name << ": 切换到频道 " << channel << std::endl;
    }

    void adjustVolume(int volume) {
        std::cout << name << ": 调整音量为 " << volume << std::endl;
    }
};

// 具体电视类:LG电视
class LGTV : public TV {
public:
    LGTV() : TV("LG TV") {}

    void powerOn() {
        std::cout << name << ": 开机" << std::endl;
    }

    void powerOff() {
        std::cout << name << ": 关机" << std::endl;
    }

    void setChannel(int channel) {
        std::cout << name << ": 切换到频道 " << channel << std::endl;
    }

    void adjustVolume(int volume) {
        std::cout << name << ": 调整音量为 " << volume << std::endl;
    }
};

// 定义遥控器的抽象类
class RemoteControl {
protected:
    TV* tv;

public:
    RemoteControl(TV* tv) : tv(tv) {}

    virtual void powerOn() = 0;
    virtual void powerOff() = 0;
    virtual void setChannel(int channel) = 0;
    virtual void adjustVolume(int volume) = 0;
};

// 具体遥控器类:普通遥控器
class BasicRemoteControl : public RemoteControl {
public:
    BasicRemoteControl(TV* tv) : RemoteControl(tv) {}

    void powerOn() {
        std::cout << "基础遥控器:";
        tv->powerOn();
    }

    void powerOff() {
        std::cout << "基础遥控器:";
        tv->powerOff();
    }

    void setChannel(int channel) {
        std::cout << "基础遥控器:";
        tv->setChannel(channel);
    }

    void adjustVolume(int volume) {
        std::cout << "基础遥控器:";
        tv->adjustVolume(volume);
    }
};

// 具体遥控器类:高级遥控器
class AdvancedRemoteControl : public RemoteControl {
public:
    AdvancedRemoteControl(TV* tv) : RemoteControl(tv) {}

    void powerOn() {
        std::cout << "高级遥控器:";
        tv->powerOn();
    }

    void powerOff() {
        std::cout << "高级遥控器:";
        tv->powerOff();
    }

    void setChannel(int channel) {
        std::cout << "高级遥控器:";
        tv->setChannel(channel);
    }

    void adjustVolume(int volume) {
        std::cout << "高级遥控器:";
        tv->adjustVolume(volume);
    }
};

int main() {
    // 创建Sony电视和普通遥控器
    TV* sonyTV = new SonyTV();
    RemoteControl* basicRemote = new BasicRemoteControl(sonyTV);

    // 使用普通遥控器操作Sony电视
    basicRemote->powerOn();
    basicRemote->setChannel(5);
    basicRemote->adjustVolume(10);
    basicRemote->powerOff();
    std::cout << std::endl;

    // 创建LG电视和高级遥控器
    TV* lgTV = new LGTV();
    RemoteControl* advancedRemote = new AdvancedRemoteControl(lgTV);

    // 使用高级遥控器操作LG电视
    advancedRemote->powerOn();
    advancedRemote->setChannel(10);
    advancedRemote->adjustVolume(20);
    advancedRemote->powerOff();

    // 释放内存
    delete sonyTV;
    delete basicRemote;
    delete lgTV;
    delete advancedRemote;

    return 0;
}

2 要点总结

Bridge 模式使用“对象间的组合关亲”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自纬度的变化,即“子类化”它们。

Bridge 模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个类只有一个变化的原因),复用性比较差。

Bridge 模式是比多继承方案更好的解决方法。

Bridge 模式的应用一般在“两个非常强的变化维度”,有时一个类也有多于两个的变化维度,这时可以使用 Bridge 的扩展模式。