• 桥接模式(Bridge Pattern) C++


    上一节:适配器模式(Adapter Pattern) C++

    0.理论

    桥接模式(Bridge Pattern)是一种结构型设计模式,它的核心思想是将抽象部分与其实现部分分离,使它们可以独立地变化。通过使用组合关系而非继承关系,桥接模式能够提高代码的可扩展性和灵活性。

    1.组件

    • 抽象化(Abstraction):这是一个抽象类,它持有一个对实现化对象的引用。抽象化定义了基于实现化对象的高层操作。
    • 细化抽象化(Refined Abstraction):这是抽象化的子类,它扩展了抽象化定义的接口。
    • 实现化(Implementor):这是一个接口或抽象类,定义了实现化角色的接口,包括它的具体实现。
    • 具体实现化(Concrete Implementor):这是实现化角色的具体实现类。

    在这里插入图片描述

    Bridge 模式的结构图中可以看到,系统被分为两个相对独立的部分,左边是抽象部分,右边是实现部分,这两个部分可以互相独立地进行修改。

    2.使用场景

    • 当一个类存在两个独立变化的维度时,可以将这两个维度分离出来,使它们可以独立地进行扩展。
    • 当一个系统需要在构建时能够选择或切换不同的实现方法时。
    • 当要避免类的继承带来的固化关系时,使得系统更加灵活、易于扩展。

    1.实践

    在游戏开发中,桥接模式可以用于分离游戏的图形渲染引擎(实现化角色)和游戏中的对象(抽象化角色),以便独立地管理和扩展它们。这种分离使得更换或升级渲染引擎,或者添加新的游戏对象变得更加灵活和简单。假设我们正在开发一个游戏,其中包含多种类型的游戏对象,如敌人、玩家角色和环境元素。这些对象需要在不同的渲染引擎上进行渲染,比如OpenGL和DirectX。

    实现化角色:渲染引擎接口

    定义两个渲染引擎的接口,分别为OpenGLRenderer和DirectXRenderer,它们都实现了一个共同的接口Renderer。

    // 渲染引擎接口
    class Renderer {
    public:
        virtual void renderShape(const std::string& shapeDescription) = 0;
        virtual ~Renderer() {}
    };
    
    // OpenGL渲染引擎
    class OpenGLRenderer : public Renderer {
    public:
        void renderShape(const std::string& shapeDescription) override {
            std::cout << "OpenGL rendering " << shapeDescription << std::endl;
        }
    };
    
    // DirectX渲染引擎
    class DirectXRenderer : public Renderer {
    public:
        void renderShape(const std::string& shapeDescription) override {
            std::cout << "DirectX rendering " << shapeDescription << std::endl;
        }
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    抽象化角色:游戏对象

    定义游戏中的抽象对象GameObject,它持有一个对渲染引擎的引用,以便于对象可以使用不同的渲染引擎进行渲染。

    // 游戏对象抽象
    class GameObject {
    protected:
        Renderer* renderer; // 渲染引擎
    public:
        GameObject(Renderer* renderer) : renderer(renderer) {}
        virtual void draw() = 0; // 绘制方法,由子类实现
        virtual ~GameObject() {}
    };
    
    // 具体游戏对象:玩家
    class Player : public GameObject {
    public:
        Player(Renderer* renderer) : GameObject(renderer) {}
        void draw() override {
            renderer->renderShape("Player");
        }
    };
    
    // 具体游戏对象:敌人
    class Enemy : public GameObject {
    public:
        Enemy(Renderer* renderer) : GameObject(renderer) {}
        void draw() override {
            renderer->renderShape("Enemy");
        }
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    在这个例子中,GameObject是抽象化角色,它定义了游戏对象的基本结构和draw方法。Player和Enemy是细化抽象化角色,它们具体实现了draw方法来描述如何绘制自己。

    现在,如果想要在游戏中使用不同的渲染引擎来渲染对象,只需要在创建游戏对象时传入不同的渲染引擎实例即可。

    Renderer* opengl = new OpenGLRenderer();
    Renderer* directx = new DirectXRenderer();
    
    GameObject* player = new Player(opengl); // 使用OpenGL渲染玩家
    GameObject* enemy = new Enemy(directx); // 使用DirectX渲染敌人
    
    player->draw(); // 输出:OpenGL rendering Player
    enemy->draw(); // 输出:DirectX rendering Enemy
    
    delete player;
    delete enemy;
    delete opengl;
    delete directx;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    实际上上面使用 Bridge 模式和使用带来问题方式的解决方案的根本区别在于是通过继承还是通过组合的方式去实现一个功能需求。

    下一节:装饰器模式 (Decorator Pattern) C++

  • 相关阅读:
    数据结构与算法之美读书笔记14
    STC不同系列单片机的软串口位时间函数差异
    山东菏泽家乡网页代码 html静态网页设计制作 dw静态网页成品模板素材网页 web前端网页设计与制作 div静态网页设计
    matlab编译.net dll及C#调用
    Python爬虫实战:自动化数据采集与分析
    进程管理学习
    元素的显示与隐藏
    SOLID之DIP-依赖反转原则
    代码随想录算法训练营 Day35 贪心算法4
    【挑战开发100个项目 | 1. C语言学生管理系统】
  • 原文地址:https://blog.csdn.net/yaoyaohyl/article/details/136303389