首页 > 编程语言 >C++ 设计模式——桥接模式

C++ 设计模式——桥接模式

时间:2024-08-29 14:26:31浏览次数:13  
标签:std pimgos 桥接 C++ 实现 ImageOS 设计模式 public

C++ 设计模式——桥接模式

C++ 设计模式——桥接模式

桥接模式是一种结构型设计模式,它将抽象部分与实现部分分离,使它们都可以独立地变化。这种模式通过组合的方式来代替继承,增加了系统的灵活性。

1. 主要组成成分

  1. 抽象类(Abstraction):定义抽象类的接口,维护一个对实现类对象的引用。
  2. 扩展抽象类(Refined Abstraction):扩展抽象类的接口。
  3. 实现类接口(Implementor):定义实现类的接口。
  4. 具体实现类(Concrete Implementor):实现实现类接口并定义具体实现。

2. 逐步构建桥接模式

以图像处理系统为例,展示桥接模式的实现,在图像处理系统中,可以识别出两个独立变化的维度:

  • 图像格式(PNG, JPG, BMP等)
  • 操作系统(Windows, Linux, Mac等)

这两个维度可以独立变化,非常适合使用桥接模式。

步骤1: 创建实现接口

创建操作系统的实现接口,此接口定义了所有操作系统都应实现的draw方法。

// 操作系统接口
class ImageOS {
public:
    // 纯虚函数,用于在特定操作系统上绘制图像
    virtual void draw(char* pData, int iLen) = 0;
    virtual ~ImageOS() {}
};
步骤2: 实现具体实现类

为不同的操作系统创建具体的实现类。

// Windows操作系统实现
class ImageOS_Windows : public ImageOS {
public:
    virtual void draw(char* pData, int iLen) override {
        std::cout << "在Windows操作系统下显示图像数据。" << std::endl;
    }
};

// Linux操作系统实现
class ImageOS_Linux : public ImageOS {
public:
    virtual void draw(char* pData, int iLen) override {
        std::cout << "在Linux操作系统下显示图像数据。" << std::endl;
    }
};

// Mac操作系统实现
class ImageOS_Mac : public ImageOS {
public:
    virtual void draw(char* pData, int iLen) override {
        std::cout << "在Mac操作系统下显示图像数据。" << std::endl;
    }
};
步骤3: 创建抽象类

创建图像格式的抽象类,这个抽象类包含一个ImageOS的指针,构成了"桥"的关键部分。

// 图像格式抽象类
class ImageFormat {
protected:
    ImageOS* m_pImgOS;  // 操作系统接口指针
public:
    ImageFormat(ImageOS* pimgos) : m_pImgOS(pimgos) {}
    // 纯虚函数,用于解析特定格式的图像文件
    virtual void parseFile(const char* pfilename) = 0;
    virtual ~ImageFormat() {}
};
步骤4: 实现扩展抽象类

为不同的图像格式创建扩展抽象类。

// PNG图像格式实现
class Image_PNG : public ImageFormat {
public:
    Image_PNG(ImageOS* pimgos) : ImageFormat(pimgos) {}
    virtual void parseFile(const char* pfilename) override {
        std::cout << "解析PNG文件数据,";
        int iLen = 100;
        std::unique_ptr<char[]> presult(new char[iLen]);
        m_pImgOS->draw(presult.get(), iLen);
    }
};

// JPG图像格式实现
class Image_JPG : public ImageFormat {
public:
    Image_JPG(ImageOS* pimgos) : ImageFormat(pimgos) {}
    virtual void parseFile(const char* pfilename) override {
        std::cout << "解析JPG文件数据,";
        // 实现细节省略
    }
};

// BMP图像格式实现
class Image_BMP : public ImageFormat {
public:
    Image_BMP(ImageOS* pimgos) : ImageFormat(pimgos) {}
    virtual void parseFile(const char* pfilename) override {
        std::cout << "解析BMP文件数据,";
        // 实现细节省略
    }
};
步骤5: 客户端使用

在客户端代码中使用这个桥接模式。

int main() {
    // 创建Windows操作系统对象
    std::unique_ptr<ImageOS> pimgos_windows = std::make_unique<ImageOS_Windows>();
    
    // 创建PNG图像格式对象,并关联到Windows操作系统
    std::unique_ptr<ImageFormat> pimg_png = std::make_unique<Image_PNG>(pimgos_windows.get());
    
    // 解析PNG文件
    pimg_png->parseFile("image.png");

    return 0;
}

3. 桥接模式 UML 图

桥接模式 UML 图

UML 图解析

桥接模式的 UML 图中包含 4 种角色:

  • Abstraction (抽象部分相关接口):定义抽象类的接口,其中包含一根指向 Implementor 类型对象的指针。这里指 ImageFormat 类。
  • RefinedAbstraction (扩充抽象部分接口):实现在 Abstraction 中定义的接口,还可以在其中调用在 Implementor 中定义的方法。这里指 Image_PNGImage_JPGImage_BMP 类。
  • Implementor (实现部分相关接口):定义实现类的接口,这些接口可能与 Abstraction 中的接口一致,也可能完全不同。通常 Implementor 中定义的接口仅提供基本操作,而 Abstraction 中定义的接口会实现更多、更复杂的功能。这里指 ImageOS 类。
  • ConcreteImplementor (实现部分具体类):实现在 Implementor 中定义的接口。这里指 ImageOS_WindowsImageOS_LinuxImageOS_Mac 类。

4. 桥接模式的优点

  1. 解耦抽象与实现:桥接模式通过将抽象部分与实现部分分离,实现了两者的解耦,使它们可以独立变化。
  2. 提高可扩展性:该模式允许在不修改现有代码的情况下,独立地扩展抽象和实现层次结构。
  3. 实现细节封装:客户端代码仅与高层抽象进行交互,无需关注底层实现细节。
  4. 改善类层次结构:通过组合代替多层继承,桥接模式减少了类的数量和复杂性。
  5. 进松耦合:抽象和实现的分离降低了系统各部分之间的依赖,有利于系统的维护和演化。

5. 桥接模式的缺点

  1. 增加设计复杂度:桥接模式要求系统具有抽象层次的设计和编程能力,可能增加初始开发的复杂度。
  2. 识别抽象和实现的难度:正确识别系统中的抽象和实现维度需要丰富的经验和深入的系统理解。
  3. 潜在的性能影响:由于引入了额外的间接层和方法调用,在某些情况下可能会轻微影响系统性能。
  4. 增加代码量:相比简单的继承方案,桥接模式通常需要更多的类和接口定义。

6. 桥接模式适用场景

  1. 多维度变化:当一个系统需要在多个维度上独立变化,且这些维度之间存在正交关系时。
  2. 跨平台开发:在需要开发跨多个平台的应用程序时,桥接模式可以有效地分离平台相关代码。
  3. 运行时切换实现:当系统需要在运行时动态切换不同实现时,桥接模式提供了灵活的结构支持。
  4. 避免类爆炸:在可能导致类层次结构急剧膨胀的情况下,桥接模式提供了一种替代多层继承的方案。
  5. 接口与实现解耦:当需要将接口与实现分离,使它们可以独立演化时。
  6. 可插拔组件:在设计可插拔的组件系统时,桥接模式可以提供清晰的结构支持。
  7. 不同维度的组合:当系统中存在多个独立的维度,需要灵活组合这些维度时。

总结

桥接模式是一种强大的设计模式,它通过将抽象部分与实现部分分离,提供了更高的灵活性和可扩展性。虽然它增加了设计的复杂度,但其带来的解耦和扩展性优势使其在许多复杂系统中成为不可或缺的设计工具。通过桥接模式,可以有效地应对多维度变化的需求,避免类爆炸,提高系统的维护性和演化能力。

完整代码

#include <iostream>
#include <memory>
#include <string>

// 操作系统接口
class ImageOS {
public:
    virtual void draw(const char* pData, int iLen) = 0;
    virtual ~ImageOS() = default;
};

// Windows操作系统实现
class ImageOS_Windows : public ImageOS {
public:
    void draw(const char* pData, int iLen) override {
        std::cout << "在Windows操作系统下显示图像数据。" << std::endl;
    }
};

// Linux操作系统实现
class ImageOS_Linux : public ImageOS {
public:
    void draw(const char* pData, int iLen) override {
        std::cout << "在Linux操作系统下显示图像数据。" << std::endl;
    }
};

// Mac操作系统实现
class ImageOS_Mac : public ImageOS {
public:
    void draw(const char* pData, int iLen) override {
        std::cout << "在Mac操作系统下显示图像数据。" << std::endl;
    }
};

// 图像格式抽象类
class ImageFormat {
protected:
    std::shared_ptr<ImageOS> m_pImgOS;
public:
    explicit ImageFormat(std::shared_ptr<ImageOS> pimgos) : m_pImgOS(std::move(pimgos)) {}
    virtual void parseFile(const std::string& filename) = 0;
    virtual ~ImageFormat() = default;
};

// PNG图像格式实现
class Image_PNG : public ImageFormat {
public:
    explicit Image_PNG(std::shared_ptr<ImageOS> pimgos) : ImageFormat(std::move(pimgos)) {}
    void parseFile(const std::string& filename) override {
        std::cout << "解析PNG文件数据:" << filename << ",";
        const int iLen = 100;
        std::unique_ptr<char[]> presult = std::make_unique<char[]>(iLen);
        m_pImgOS->draw(presult.get(), iLen);
    }
};

// JPG图像格式实现
class Image_JPG : public ImageFormat {
public:
    explicit Image_JPG(std::shared_ptr<ImageOS> pimgos) : ImageFormat(std::move(pimgos)) {}
    void parseFile(const std::string& filename) override {
        std::cout << "解析JPG文件数据:" << filename << ",";
        // 实现细节省略
        m_pImgOS->draw(nullptr, 0);
    }
};

// BMP图像格式实现
class Image_BMP : public ImageFormat {
public:
    explicit Image_BMP(std::shared_ptr<ImageOS> pimgos) : ImageFormat(std::move(pimgos)) {}
    void parseFile(const std::string& filename) override {
        std::cout << "解析BMP文件数据:" << filename << ",";
        // 实现细节省略
        m_pImgOS->draw(nullptr, 0);
    }
};

int main() {
    // 创建不同操作系统对象
    auto windows_os = std::make_shared<ImageOS_Windows>();
    auto linux_os = std::make_shared<ImageOS_Linux>();
    auto mac_os = std::make_shared<ImageOS_Mac>();

    // 创建不同图像格式对象,并关联到不同操作系统
    auto png_windows = std::make_unique<Image_PNG>(windows_os);
    auto jpg_linux = std::make_unique<Image_JPG>(linux_os);
    auto bmp_mac = std::make_unique<Image_BMP>(mac_os);

    // 解析不同格式的图像文件
    png_windows->parseFile("image.png");
    jpg_linux->parseFile("photo.jpg");
    bmp_mac->parseFile("picture.bmp");

    return 0;
}

标签:std,pimgos,桥接,C++,实现,ImageOS,设计模式,public
From: https://blog.csdn.net/qq_68194402/article/details/141614577

相关文章

  • c++数组挑战-字符环
    题目描述:有两个由字符构成的环。请写一个程序,计算这两个字符环上最长连续公共字符串的长度。例如,字符串 ABCEFAGADEGKABUVKLM 的首尾连在一起,构成一个环;字符串 MADJKLUVKL 的首尾连在一起,构成一个另一个环; UVKLMA 是这两个环的一个连续公共字符串。时间限制:1 s内存限......
  • 【性能优化】:设计模式与技术方案解析(二)
    引言在【性能优化】:探索系统瓶颈的根源(一)文章中,我们已经分析了手动结算的弊端和瓶颈,本文来分析下怎么优化系统性能。需求分析既然手动结算耗时费力易出错,那么能不能开发一个**程序自动化处理**呢?如果要开发一个自动化跑批的程序,核心功能点是什么呢?第一:需要能正常运行;......
  • Java设计模式之原型模式详细讲解和案例示范
    引言在软件设计中,设计模式为我们提供了可复用的解决方案,以应对常见的设计问题。原型模式(PrototypePattern)是创建型设计模式的一种,它允许通过复制现有对象来创建新对象,而不需要了解创建过程的细节。本文将详细探讨原型模式,结合电商交易系统中的具体案例,深入讲解其使用场景......
  • 用c/c++做一个扫雷游戏
    “扫雷”想必80 90年代的都不陌生吧,是当代青年人机必备的益智游戏,今天,我们就用c/c++还原它,记得点赞支持一下,老乔谢谢你们~使用演示设备:1.开发环境 visualstudio2022 或 devc++2.演示系统Windows103.演示课目扫雷游戏效果展示(演示图):上代码:#include<stdio......
  • AirSlam C++ 代码学习
    问题1:reserve函数是什么?reserve是C++标准库中std::vector类的一个成员函数,用于预留一定数量的内存空间,以避免在向量增长时频繁进行内存分配和复制操作,从而提高性能。具体来说,reserve(n)会为向量预留至少n个元素的内存空间,但不会改变向量的大小(即不会添加任何元素)。这......
  • 《C++中的友元:打破封装的神秘力量》
    在C++的编程世界里,友元函数和友元类就像是一把特殊的钥匙,可以打开封装的大门,让特定的函数或类能够访问其他类的私有成员。这一特性在某些情况下具有重要的作用,让我们一起来深入探讨C++中的友元函数和友元类有什么作用。一、热点关注:友元为何引发热议?在面向对象编程中,封......
  • 最简最速!C++版OpenCV安装配置教程Win/Mac!!!
    Clion+OpenCV(C++版)开发环境配置教程Win/Mac        平时在学习和比赛的时候都是使用的Python版本的OpenCV,最近遇到了一个项目使用的上位机性能有限于是决定视觉方面使用C++的OpenCV来节约上位机资源提高运行的速度,在查阅了网上的各种资料后发现这些资料参差不齐......
  • Clion+OpenCV(C++版)开发环境配置教程WinMac
    Clion+OpenCV(C++版)开发环境配置教程Win/Mac        平时在学习和比赛的时候都是使用的Python版本的OpenCV,最近遇到了一个项目使用的上位机性能有限于是决定视觉方面使用C++的OpenCV来节约上位机资源提高运行的速度,在查阅了网上的各种资料后发现这些资料参差不齐有些博......
  • 【设计模式】单例模式(线程安全)
     ......
  • C++入门基础(内容太干,噎住了)
    文章目录1.缺省参数2.函数重载2.1重载条件:1.参数类型不同2.参数个数不同3.参数类型顺序不同 2.2不做重载条件情况:1.返回值相同时2.当全缺省遇见无参数3.引用3.1引用特性:3.2引用的使用1.缺省参数1.缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。......