面向对象编程思想-桥接模式

一、引言

最近朋友打算购置一台电脑,在考虑购买台式机还是组装机?但是台式机和组装机到底有什么区别呢?台式机由已经固定好硬件组成,我们可以是选择不同的牌子,具体设计类图如下

这样实现不同品牌的电脑都有自己的电脑组成实现,嗯?这样是不是挺好的,将电脑组装抽象出来,如果要加一个品牌为戴尔的电脑,只需要再写一个电脑派生类便可以。可实际生活中电脑只做这些事情是远远不能满足人们的需要的,如果用户要电脑新增加听音乐功能,就需要修改电脑抽象类提供的接口,这将导致所有品牌电脑都需要修改。设想假如需要同时新增电脑品牌和功能的时候,上图的设计将需要大量的修改,显然这样的设计不是好的设计。那如何设计才能让程序变得更优雅呢?下面请看我们今天学习的桥接模式是如何很好的解决这个问题的

二、桥接模式

定义:将抽象部分与它的实际部分分离,使它们都可以独立的变化。

合成/聚合复用原则:尽量使用合成聚合,尽量不要使用继承。聚合表示一种弱的拥有关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分。合成则是一种强的拥有关系,体现的是严格的部分和整体的关系,部分和整体的生命周期是一样。

下面是代码demo

     //手机软件抽象类
  public abstract class HandSetSoft { public abstract string Run(); }
     //手机上的游戏软件
  class HandSetGame : HandSetSoft { public override string Run() { return "游戏"; } }
   //手机上的通讯录软件
   class
HandSetAdressList : HandSetSoft { public override string Run() { return "通讯录"; } }
  //手机品牌抽象类
   public abstract class HandSetBrand { protected HandSetSoft soft;
    //设置手机软件(品牌需要关注手机软件,所以可以在机器上安装软件,以备运行)
public void SetHandSoft(HandSetSoft handSoft) { this.soft = handSoft; }
    //运行
public abstract void Run(); }
  //具体的手机品牌M
  class
HandSetMBrand : HandSetBrand { public override void Run() { Console.WriteLine($"use {this.GetType().Name} 上的 {soft.Run()}"); } }
   //具体的手机品牌N
  class HandSetNBrand : HandSetBrand { public override void Run() { Console.WriteLine($"use {this.GetType().Name} 上的 {soft.Run()}"); } }
    //客户端调用代码
    static
void Main(string[] args) { HandSetBrand brandm = new HandSetMBrand(); brandm.SetHandSoft(new HandSetGame()); brandm.Run(); HandSetBrand brandn = new HandSetNBrand(); brandn.SetHandSoft(new HandSetAdressList()); brandn.Run(); Console.Read(); }

分析:上面的桥接模式中,手机软件打游戏、通讯录功能不再在手机品牌中实现了,而是把实现部分用另一个手机软件类封装,在手机品牌中添加对手机软件类的引用,这样就很好的避免了更改一个维度时带给另一个维护影响。现实生活中,Apple手机中的AppStore商店,是不是就符合这种程序设计思想呢。通过桥接模式,我们把抽象部分和实现部分分离开了,这样就很好的应对两方面的变化了。

优点:抽象接口与实现解耦;两个维度上可以独立变化,扩展互不影响;隐藏实现的具体细节

缺点:增加了系统的复杂度

使用场景:实现系统可能有多角度分类,每一种分类都有可能变化,那么就把这种多角度分离出来让它们独立变化,减少它们之间的耦合。(解决一个类多维度变化的问题)

关于桥接模式的学习就到此结束了,希望能够帮到你,若有不足,欢迎斧正,感谢您的阅读。

原文地址:https://www.cnblogs.com/jdzhang/p/7018368.html