六、桥接模式——将多重继承增加一个旁路

本文介绍了桥接模式的概念及其应用场景,通过实例演示了如何利用桥接模式来减少子类数量并提高系统的灵活性和可扩展性。文章还展示了桥接模式的具体实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


设计模式是面向问题、场景而总结产生的设计思路。是解决问题的套路。23 种经典的设计模式。它们又可以分为三大类:创建型、结构型、行为型。

结构型 包含了 代理模式、 桥接模式、 装饰器模式、适配器模式、门面模式、组合模式、 享元模式。

桥接模式

桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。

1. 为什么使用桥接模式

桥接模式使用组合代替继承,使系统更加灵活,并易于扩展,同时有效控制了系统中类的个数。

在很多情况下,桥接模式可以取代多层继承方案,多层继承方案违背了“单一职责原则”,复用性较差,且类的个数非常多,桥接模式是比多层继承方案更好的解决方法,它极大减少了子类的个数。

如果某个类存在两个独立变化的维度,可以运用桥接模式将这两个维度分离出来,使两者可以独立扩展,让系统更加符合“单一职责原则”。桥接模式提高了系统的可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统,符合“开闭原则”。

2.使用桥接模式

桥接模式定义了四个角色,
Abstraction,持有Implementor,Implementor是代表了另一个维度。
RefinedAbstraction,继承Abstraction,因此可以调用在Implementor中定义的业务方法。
Implementor,定义了业务功能。
ConcreteImplementor,具体实现Implementor接口。

2.1 Abstraction

Abstraction角色,比如电脑类,持有一个对象,是操作系统。

public abstract class Computer {
    protected OperationSystem os;

    public Computer(OperationSystem os) {
        this.os = os;
    }

    public abstract void work();
}

2.2 RefinedAbstraction

比如苹果电脑、戴尔电脑等。

public class AppleComputer extends Computer{

    public AppleComputer(OperationSystem os) {
        super(os);
    }

    @Override
    public void work() {
        System.out.println("Apple 笔记本,开机启动");
        os.run();
    }
}

public class DellComputer extends Computer{

    public DellComputer(OperationSystem os) {
        super(os);
    }

    @Override
    public void work() {
        System.out.println("Dell 笔记本,开机启动");
        os.run();
    }
}

2.3 Implementor

定义操作系统类

public abstract class OperationSystem {
    public abstract void run();
}

2.4 ConcreteImplementor

可以有linux、windows、macos等操作系统。

public class LinuxOperationSystem extends OperationSystem{
    @Override
    public void run() {
        System.out.println("Linux操作系统,操作系统加载");
    }
}

public class WindowsOperationSystem extends OperationSystem{
    @Override
    public void run() {
        System.out.println("windows操作系统,操作系统加载");
    }
}

public class MacOperationSystem extends OperationSystem{
    @Override
    public void run() {
        System.out.println("Mac操作系统,操作系统加载");
    }
}

2.5 将大家组合起来

由于两个维度的解离,可以实现各种组合。

public class Main {
    public static void main(String[] args) {
        Computer computer = new DellComputer(new WindowsOperationSystem());
        computer.work();

        Computer computer2 = new DellComputer(new LinuxOperationSystem());
        computer2.work();

        Computer computer3 = new AppleComputer(new MacOperationSystem());
        computer3.work();
    }
}

运行如下

Dell 笔记本,开机启动
windows操作系统,操作系统加载
Dell 笔记本,开机启动
Linux操作系统,操作系统加载
Apple 笔记本,开机启动
Mac操作系统,操作系统加载

总结

在使用桥接模式时,首先应该识别出一个类所具有的两个独立变化的维度,将它们设计为两个独立的继承等级结构,为两个维度都提供抽象层,并建立抽象耦合。
  
模式系列在github上有一个开源项目,主要是本系列博客的demo代码。https://github.com/forestnlp/designpattern
如果您对软件开发、机器学习、深度学习有兴趣请关注本博客,将持续推出Java、软件架构、深度学习相关专栏。
您的支持是对我最大的鼓励。

桥接模式是一种结构型设计模式,它将抽象和实现分离,使它们可以独立地变化。桥接模式的核心思想是将一个大类或一组类分解成抽象和实现两个独立的维度,使它们可以独立地变化和扩展,同时通过桥接来将它们连接起来。 在C++中,桥接模式通常通过虚函数实现。抽象部分通过基类定义接口,而实现部分通过派生类实现具体的功能。通过将抽象部分的指针作为参数传递给实现部分的函数,就可以实现两个部分的连接。 下面是一个简单的桥接模式的C++示例: ```c++ class Implementor { public: virtual void operation() = 0; virtual ~Implementor() {} }; class ConcreteImplementorA : public Implementor { public: void operation() override { // 具体的实现A } }; class ConcreteImplementorB : public Implementor { public: void operation() override { // 具体的实现B } }; class Abstraction { public: Abstraction(Implementor* implementor) : m_implementor(implementor) {} virtual void operation() = 0; virtual ~Abstraction() {} protected: Implementor* m_implementor; }; class RefinedAbstraction : public Abstraction { public: RefinedAbstraction(Implementor* implementor) : Abstraction(implementor) {} void operation() override { m_implementor->operation(); // 其他操作 } }; int main() { Implementor* implementorA = new ConcreteImplementorA(); Implementor* implementorB = new ConcreteImplementorB(); Abstraction* abstractionA = new RefinedAbstraction(implementorA); Abstraction* abstractionB = new RefinedAbstraction(implementorB); abstractionA->operation(); abstractionB->operation(); delete abstractionA; delete abstractionB; delete implementorA; delete implementorB; return 0; } ``` 在上面的示例中,Implementor是实现部分的抽象基类,ConcreteImplementorA和ConcreteImplementorB是具体的实现类。Abstraction是抽象部分的基类,RefinedAbstraction是抽象部分的具体实现类。在main函数中,我们创建了不同的Implementor和Abstraction对象,并通过它们来完成不同的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟空学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值