桥接模式(Bridge Pattern)及其应用场景

桥接模式是一种结构型设计模式,它将抽象部分与实现部分分离,使它们可以独立变化。

模式定义

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

模式结构

  • Abstraction(抽象部分): 定义抽象类的接口,维护一个指向实现类对象的引用

  • RefinedAbstraction(扩展抽象部分): 扩展抽象部分的接口

  • Implementor(实现者接口): 定义实现类的接口

  • ConcreteImplementor(具体实现者): 实现实现者接口

应用场景

  1. 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时

  2. 当一个系统需要在构件的抽象角色和具体角色之间增加更多的灵活性时

  3. 当不希望使用继承或因为多层继承导致系统类的个数急剧增加时

  4. 当一个系统需要在运行时切换不同的实现时

优点

  1. 分离抽象接口及其实现部分

  2. 提高了系统的可扩展性

  3. 实现细节对客户透明

  4. 避免了多层继承带来的复杂性

缺点

  1. 增加了系统的理解与设计难度

  2. 需要正确地识别出系统中两个独立变化的维度

C++实用示例

示例1:图形绘制系统

#include <iostream>
#include <string>

// 实现部分接口
class Renderer {
public:
    virtual void renderCircle(float x, float y, float radius) = 0;
    virtual ~Renderer() = default;
};

// 具体实现1
class VectorRenderer : public Renderer {
public:
    void renderCircle(float x, float y, float radius) override {
        std::cout << "Drawing a vector circle of radius " << radius 
                  << " at (" << x << ", " << y << ")\n";
    }
};

// 具体实现2
class RasterRenderer : public Renderer {
public:
    void renderCircle(float x, float y, float radius) override {
        std::cout << "Drawing a raster circle of radius " << radius 
                  << " at (" << x << ", " << y << ")\n";
    }
};

// 抽象部分
class Shape {
protected:
    Renderer& renderer;
    Shape(Renderer& renderer) : renderer(renderer) {}
public:
    virtual void draw() = 0;
    virtual void resize(float factor) = 0;
    virtual ~Shape() = default;
};

// 扩展抽象部分
class Circle : public Shape {
    float x, y, radius;
public:
    Circle(Renderer& renderer, float x, float y, float radius)
        : Shape(renderer), x(x), y(y), radius(radius) {}
    
    void draw() override {
        renderer.renderCircle(x, y, radius);
    }
    
    void resize(float factor) override {
        radius *= factor;
    }
};

int main() {
    VectorRenderer vr;
    RasterRenderer rr;

    Circle vectorCircle(vr, 5, 5, 10);
    Circle rasterCircle(rr, 20, 20, 5);

    vectorCircle.draw();
    rasterCircle.draw();

    vectorCircle.resize(2);
    vectorCircle.draw();
}

示例2:设备与远程控制

#include <iostream>
#include <string>

// 实现部分接口
class Device {
public:
    virtual bool isEnabled() = 0;
    virtual void enable() = 0;
    virtual void disable() = 0;
    virtual int getVolume() = 0;
    virtual void setVolume(int percent) = 0;
    virtual int getChannel() = 0;
    virtual void setChannel(int channel) = 0;
    virtual ~Device() = default;
};

// 具体实现1
class TV : public Device {
    bool on = false;
    int volume = 50;
    int channel = 1;
public:
    bool isEnabled() override { return on; }
    void enable() override { on = true; }
    void disable() override { on = false; }
    int getVolume() override { return volume; }
    void setVolume(int percent) override { volume = percent; }
    int getChannel() override { return channel; }
    void setChannel(int channel) override { this->channel = channel; }
};

// 具体实现2
class Radio : public Device {
    bool on = false;
    int volume = 30;
    int channel = 1;
public:
    bool isEnabled() override { return on; }
    void enable() override { on = true; }
    void disable() override { on = false; }
    int getVolume() override { return volume; }
    void setVolume(int percent) override { volume = percent; }
    int getChannel() override { return channel; }
    void setChannel(int channel) override { this->channel = channel; }
};

// 抽象部分
class RemoteControl {
protected:
    Device* device;
public:
    RemoteControl(Device* device) : device(device) {}
    virtual void togglePower() {
        if (device->isEnabled()) {
            device->disable();
            std::cout << "Device turned off\n";
        } else {
            device->enable();
            std::cout << "Device turned on\n";
        }
    }
    virtual void volumeUp() {
        device->setVolume(device->getVolume() + 10);
        std::cout << "Volume set to " << device->getVolume() << "\n";
    }
    virtual void volumeDown() {
        device->setVolume(device->getVolume() - 10);
        std::cout << "Volume set to " << device->getVolume() << "\n";
    }
    virtual void channelUp() {
        device->setChannel(device->getChannel() + 1);
        std::cout << "Channel set to " << device->getChannel() << "\n";
    }
    virtual void channelDown() {
        device->setChannel(device->getChannel() - 1);
        std::cout << "Channel set to " << device->getChannel() << "\n";
    }
    virtual ~RemoteControl() = default;
};

// 扩展抽象部分
class AdvancedRemoteControl : public RemoteControl {
public:
    AdvancedRemoteControl(Device* device) : RemoteControl(device) {}
    void mute() {
        device->setVolume(0);
        std::cout << "Device muted\n";
    }
};

int main() {
    TV tv;
    Radio radio;

    RemoteControl basicRemote(&tv);
    AdvancedRemoteControl advancedRemote(&radio);

    basicRemote.togglePower();
    basicRemote.volumeUp();
    basicRemote.channelUp();

    advancedRemote.togglePower();
    advancedRemote.volumeUp();
    advancedRemote.mute();
}

示例3:日志记录系统

#include <iostream>
#include <string>
#include <fstream>

// 实现部分接口
class LoggerImpl {
public:
    virtual void log(const std::string& message) = 0;
    virtual ~LoggerImpl() = default;
};

// 具体实现1 - 控制台日志
class ConsoleLogger : public LoggerImpl {
public:
    void log(const std::string& message) override {
        std::cout << "Console: " << message << std::endl;
    }
};

// 具体实现2 - 文件日志
class FileLogger : public LoggerImpl {
    std::string filename;
public:
    FileLogger(const std::string& filename) : filename(filename) {}
    void log(const std::string& message) override {
        std::ofstream file(filename, std::ios_base::app);
        if (file.is_open()) {
            file << "File: " << message << std::endl;
        }
    }
};

// 抽象部分
class Logger {
protected:
    LoggerImpl* impl;
public:
    Logger(LoggerImpl* impl) : impl(impl) {}
    virtual void log(const std::string& message) = 0;
    virtual ~Logger() { delete impl; }
};

// 扩展抽象部分1 - 简单日志
class SimpleLogger : public Logger {
public:
    SimpleLogger(LoggerImpl* impl) : Logger(impl) {}
    void log(const std::string& message) override {
        impl->log(message);
    }
};

// 扩展抽象部分2 - 带时间戳的日志
class TimeStampedLogger : public Logger {
public:
    TimeStampedLogger(LoggerImpl* impl) : Logger(impl) {}
    void log(const std::string& message) override {
        time_t now = time(0);
        std::string timeStr = ctime(&now);
        timeStr.erase(timeStr.length() - 1); // 移除换行符
        impl->log(timeStr + ": " + message);
    }
};

int main() {
    Logger* consoleLogger = new SimpleLogger(new ConsoleLogger());
    Logger* fileLogger = new TimeStampedLogger(new FileLogger("log.txt"));

    consoleLogger->log("This is a simple console message");
    fileLogger->log("This message will be saved to file with timestamp");

    delete consoleLogger;
    delete fileLogger;
}

桥接模式在这些示例中展示了如何将抽象(如形状、远程控制、日志记录器)与实现(如渲染器、设备、日志输出方式)分离,使得两者可以独立变化而不互相影响。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值