分享

设计模式学习笔记(八)——Bridge桥接模式

 skywood 2007-08-06

       Bridge桥接模式是一种结构型模式,它主要应对的是:由于类型的固有罗辑,使得类型具有两个或两个以上的纬度变化。也就是要求抽象不应依赖于实现细节,实现细节应依赖于抽象。

       《设计模式》中说到将抽象部分与实现部分分离,使他们可以独立的变化。

       举个例子更清楚些,好像我们平时玩的游戏中有PS版的,但是不是大家都有PS。这时我们等一段时间,一般会出PC版的或其他版本。由于支持游戏的平台不一样,但是如果我们编写的游戏程序为了适应另一种平台就要全部重新编写的话岂不是很麻烦。再加上游戏本身的变动,一句众人皆知的话:“死定了

       现在我们来看看Bridge桥接模式,看看它是如何解决类似问题的,首先我们看看Bridge模式的结构。


      
实际上,我们要做到的是把变化的部分提出,对其抽象,使变化独立。那我们如何做呢?通过组合的方式将变化独立出去。将一个事物中的多个纬度变化分离。

       下面举一个场景来理解一下,还是用汽车举例,我现在要一辆车(BMWBORA)在路(WaterRoadCement)上跑。现在有两个纬度的变化点:汽车和路。也就是上图中的AbstractChangePoint1AbstractChangePoint2AbstractChangePoint1中包含有AbstractChangePoint2对象成员。。代码实现如下:

       abstract class AbstractCar

    {

        public AbstractRoad road;

 

        public AbstractCar(AbstractRoad road)

        {

            this.road = road;

        }

 

        public abstract string Run();

        public abstract string Stop();

    }

 

    abstract class AbstractRoad

    {

        public abstract string GetRoadType();

}

以汽车为变化中心,用组装的方式将两个变化点结合起来。使路的变化和汽车隔离。下面来编写路的实现。

class WaterRoad:AbstractRoad

    {

        public override string GetRoadType()

        {

            return "It is WaterRoad";

        }

 }

class CementRoad:AbstractRoad

    {

        public override string GetRoadType()

        {

            return "It is Cement";

        }

}

然后再来编写汽车的实现

class BMWCar:AbstractCar

    {

        public BMWCar(AbstractRoad road)

            : base(road)

        {

          

        }

 

        public override string Run()

        {

            return "BMW is running";

        }

 

        public override string Stop()

        {

            return "BMW is stopped";

        }

 }

class BROACar:AbstractCar

    {

        public BROACar(AbstractRoad road)

            : base(road)

        {

           

        }

 

        public override string Run()

        {

            return "BROA is running";

        }

 

        public override string Stop()

        {

            return "BROA is stopped";

        }

  }

然后我们在客户代码中调用这些类,首先,我想要这个场景是BMWWaterRoad上跑,客户端代码如下:

static void Main(string[] args)

        {

            AbstractCar car = new BMWCar(new WaterRoad());

            Console.WriteLine(car.road.GetRoadType());

            Console.WriteLine(car.Run());

            Console.WriteLine(car.Stop());

            Console.Read();

        }

实现结果如下:

It is WaterRoad

BMW is running

BMW is stopped

如果我现在要一辆BORACement上跑,我们只要稍微修改一下car的实例化就可以,代码如下:

static void Main(string[] args)

        {

            AbstractCar car = new BROACar(new CementRoad());

            Console.WriteLine(car.road.GetRoadType());

            Console.WriteLine(car.Run());

            Console.WriteLine(car.Stop());

            Console.Read();

     }

实现结果如下:

It is Cement

BROA is running

BROA is stopped

       最后我们再来说说Bridge模式的要点:

       1Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的纬度来变化。

2、所谓抽象和实现沿着各自纬度的变化,即“子类化”它们,得到各个子类之后,便可以任意组合它们。

3Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。

4Bridge模式的应用一般在“两个非常强的变化纬度”,有时候即使有两个变化的纬度,但是某个方向的变化纬度并不剧烈——换言之两个变化不会导致纵横交错的结果,并不一定要使用Bridge模式。

posted on 2006-05-31 09:02 KiddLee 阅读(1516) 评论(10)  编辑 收藏 引用 网摘 所属分类: 设计模式

FeedBack:
# 
中午和TerryList一起吃饭,他提示我抽象类应用斜体字。哈哈,不好意思,刚开始用UML图表示,在画的时候有很多不注意的地方,还望大家多多指教。  回复  更多评论
  
# re: 设计模式学习笔记(八)——Bridge桥接模式 2006-05-31 16:14 TerryLee
@kid_li

大哥,我叫TerryLee,不是TerryList:-)  回复  更多评论
  
# re: 设计模式学习笔记(八)——Bridge桥接模式 2006-05-31 17:40 kid_li
@TerryLee
不好意思,不小心写错了  回复  更多评论
  
# re: 设计模式学习笔记(八)——Bridge桥接模式 2006-06-01 11:31 公木子
花了一个上午的时间全部看完了你写的八种模式设计,写得不错。如果你能把23种都写完的话,希望你能写个总结就想下面的一样,很容易混淆的
Singleton单件模式解决的问题是:实体对象个数问题(这个现在还不太容易混)

AbstractFactory抽象工厂模式解决的问题是:“一系列互相依赖的对象”的创建工作

Builder生成器模式解决的问题是:“一些复杂对象”的创建工作,子对象变化较频繁,对算法相对稳定

FactoryMethor工厂方法模式解决的问题是:某个对象的创建工作

  回复  更多评论
  
# re: 设计模式学习笔记(八)——Bridge桥接模式 2006-06-01 11:31 公木子
花了一个上午的时间全部看完了你写的八种模式设计,写得不错。如果你能把23种都写完的话,希望你能写个总结就想下面的一样,很容易混淆的
Singleton单件模式解决的问题是:实体对象个数问题(这个现在还不太容易混)

AbstractFactory抽象工厂模式解决的问题是:“一系列互相依赖的对象”的创建工作

Builder生成器模式解决的问题是:“一些复杂对象”的创建工作,子对象变化较频繁,对算法相对稳定

FactoryMethor工厂方法模式解决的问题是:某个对象的创建工作

  回复  更多评论
  
# re: 设计模式学习笔记(八)——Bridge桥接模式 2006-06-01 11:31 公木子
花了一个上午的时间全部看完了你写的八种模式设计,写得不错。如果你能把23种都写完的话,希望你能写个总结就想下面的一样,很容易混淆的
Singleton单件模式解决的问题是:实体对象个数问题(这个现在还不太容易混)

AbstractFactory抽象工厂模式解决的问题是:“一系列互相依赖的对象”的创建工作

Builder生成器模式解决的问题是:“一些复杂对象”的创建工作,子对象变化较频繁,对算法相对稳定

FactoryMethor工厂方法模式解决的问题是:某个对象的创建工作

  回复  更多评论
  
# re: 设计模式学习笔记(八)——Bridge桥接模式 2006-06-01 11:31 公木子
花了一个上午的时间全部看完了你写的八种模式设计,写得不错。如果你能把23种都写完的话,希望你能写个总结就想下面的一样,很容易混淆的
Singleton单件模式解决的问题是:实体对象个数问题(这个现在还不太容易混)

AbstractFactory抽象工厂模式解决的问题是:“一系列互相依赖的对象”的创建工作

Builder生成器模式解决的问题是:“一些复杂对象”的创建工作,子对象变化较频繁,对算法相对稳定

FactoryMethor工厂方法模式解决的问题是:某个对象的创建工作

  回复  更多评论
  
# re: 设计模式学习笔记(八)——Bridge桥接模式 2006-06-01 11:54 kid_li
@公木子
哈哈,谢谢你的支持,没问题,我会的  回复  更多评论
  
# re: 设计模式学习笔记(八)——Bridge桥接模式 2006-07-11 15:34 大雁
写 得不错,例子也好,比板桥里人写得好。最后的总结很经典,支持。只是AbstractChangPoint2与AbstractChangPoint1之 间是不是应该用聚集的符号?另外,ClientApp放在这没必要吧。仅供参考,呵呵,我写了这个例子的UML图,可惜贴不上...  回复  更多评论
  
# re: 设计模式学习笔记(八)——Bridge桥接模式 2006-07-11 20:34 kid_li
@大雁
我不是很会画UML图,可不可以画一张用Email(kid_li@126.com)发给我给我学习一下。谢谢了  回复  更多评论

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多