写点什么

软件设计模式: 桥接模式

作者:正向成长
  • 2022 年 4 月 09 日
  • 本文字数:1472 字

    阅读完需:约 5 分钟

软件设计模式:桥接模式

桥接模式(Bridge),是结构性模式的一种,将抽象部分与它的实现部分分离,使它们都可以独立地变化。

场景描述


目前有 Windows、Linux 两种种操作系统,在操作系统上运行不同图片格式图片处理程序,有 PNG、JPG 等格式,同时还会有文本编辑软件,可以按照操作系统和应用软件两种角度构建类继承关系图,此时如果需要添加了 Mac 操作系统,或者 Office 办公软件,会导致类数量出现爆炸式增长,桥接模式将抽象部分(一般指业务实现,本例中的应用软件)和实现部分(一般指具体平台实现,本例中的操作系统)分开,利用聚合关系,从而避免了子类数量的爆炸式增长。



设计模式思想

对象的继承关系是在编译时就定义好了,所以无法在运行时改变从父类继承的实现。子类的实现与它的父类有非常紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类发生变化。当你需要复用子类时,如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用[1]。


在面向对象设计中,有一个很重要的设计原则,那就是合成/聚合复用原则。即优先使用对象合成/聚合(CARP),尽量使用合成/聚合,尽量不要使用类继承。优先使用对象的合成/聚合将有助于你保持每个类被封装,并被集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。


合成(Composition,也有翻译成组合)和聚合(Aggregation)都是关联的特殊种类。聚合表示一种弱的‘拥有’关系,体现的是 A 对象可以包含 B 对象,但 B 对象不是 A 对象的一部分;合成则是一种强的‘拥有’关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。



源码实现

// 操作系统抽象class ImageOS {public:    virtual void draw(const char* data) = 0;    virtual ~ImageOS() {};};
class ImageOSWin : public ImageOS {public: virtual void draw(const char* data) { std::cout << "Windows System draw image data" << std::endl; }};
class ImageOSLinux : public ImageOS {public: virtual void draw(const char* data) { std::cout << "Linux System draw image data" << std::endl; }};
class ImageOSMac : public ImageOS {public: virtual void draw(const char* data) { std::cout << "Mac System draw image data" << std::endl; }};
// 图像格式抽象class ImageFormat {public: ImageFormat(ImageOS* imageOS) : imageos_(imageOS) {}; virtual void parseFile(const char* fileName) = 0; virtual ~ImageFormat() {};
protected: ImageOS* imageos_;};
class ImageJPG : public ImageFormat {public: ImageJPG(ImageOS* imageOS) : ImageFormat(imageOS) {}; virtual void parseFile(const char* fileName) { std::cout << "Parse JPG file" << fileName << std::endl; // 模拟数据 char* imageData = new char[128]; imageos_->draw(imageData); delete imageData; }};
class ImagePNG : public ImageFormat {public: ImagePNG(ImageOS* imageOS) : ImageFormat(imageOS) {}; virtual void parseFile(const char* fileName) { std::cout << "Parse PNG file" << fileName << std::endl; // 模拟数据 char* imageData = new char[128]; imageos_->draw(imageData); delete imageData; }};
复制代码

源码实现

参考资料

  • 大话设计模式

发布于: 刚刚阅读数: 2
用户头像

正向成长

关注

正向成长 2018.08.06 加入

想要坚定地做大规模数据处理(流数据方向),希望结合结合批处理的传统处理方式,以及之后流批混合处理方向进行学习和记录。

评论

发布
暂无评论
软件设计模式:桥接模式_设计模式_正向成长_InfoQ写作平台