First we try, then we trust

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  183 随笔 :: 111 文章 :: 2984 评论 :: 339 引用

我想大家小时候都有用蜡笔画画的经历吧。红红绿绿的蜡笔一大盒,根据想象描绘出格式图样。而毛笔下的国画更是工笔写意,各展风采。而今天我们的故事从蜡笔与毛笔说起。

设想要绘制一幅图画,蓝天、白云、绿树、小鸟,如果画面尺寸很大,那么用蜡笔绘制就会遇到点麻烦。毕竟细细的蜡笔要涂出一片蓝天,是有些麻烦。如果有可能,最好有套大号蜡笔,粗粗的蜡笔很快能涂抹完成。至于色彩吗,最好每种颜色来支粗的,除了蓝天还有绿地呢。这样,如果一套12种颜色的蜡笔,我们需要两套24支,同种颜色的一粗一细。呵呵,画还没画,开始做梦了:要是再有一套中号蜡笔就更好了,这样,不多不少总共36支蜡笔。

 

再看看毛笔这一边,居然如此简陋:一套水彩12色,外加大中小三支毛笔。你可别小瞧这"简陋"的组合,画蓝天用大毛笔,画小鸟用小毛笔,各具特色。

 

呵呵,您是不是已经看出来了,不错,我今天要说的就是Bridge模式。为了一幅画,我们需要准备36支型号不同的蜡笔,而改用毛笔三支就够了,当然还要搭配上12种颜料。通过Bridge模式,我们把乘法运算3×12=36改为了加法运算3+12=15,这一改进可不小。那么我们这里蜡笔和毛笔到底有什么区别呢?

实际上,蜡笔和毛笔的关键一个区别就在于笔和颜色是否能够分离。【GOF95】桥梁模式的用意是"将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化"。关键就在于能否脱耦。蜡笔的颜色和蜡笔本身是分不开的,所以就造成必须使用36支色彩、大小各异的蜡笔来绘制图画。而毛笔与颜料能够很好的脱耦,各自独立变化,便简化了操作。在这里,抽象层面的概念是:"毛笔用颜料作画",而在实现时,毛笔有大中小三号,颜料有红绿蓝等12种,于是便可出现3×12种组合。每个参与者(毛笔与颜料)都可以在自己的自由度上随意转换。

蜡笔由于无法将笔与颜色分离,造成笔与颜色两个自由度无法单独变化,使得只有创建36种对象才能完成任务。Bridge模式将继承关系转换为组合关系,从而降低了系统间的耦合,减少了代码编写量。但这仅仅是Bridge模式带来的众多好处的一部分,更多层面的内容,请参考《设计模式(16)-Bridge Pattern》。

本文代码附于此处:

using System;

abstract class Brush
{
  
protected Color c;
  
public abstract void Paint();

  
public void SetColor(Color c)
  
this.c = c; }
}


class BigBrush : Brush
{
  
public override void Paint()
  
{ Console.WriteLine("Using big brush and color {0} painting", c.color); }
}


class SmallBrush : Brush
{
  
public override void Paint()
  
{ Console.WriteLine("Using small brush and color {0} painting", c.color); }
}


class Color
{
  
public string color;
}


class Red : Color
{
  
public Red()
  
this.color = "red"; }
}


class Blue : Color
{
  
public Blue()
  
this.color = "blue"; }
}


class Green : Color
{
  
public Green()
  
this.color = "green"; }
}


class Client
{
  
public static void Main()
  
{
    Brush b 
= new BigBrush();
    b.SetColor(
new Red());
    b.Paint();
    b.SetColor(
new Blue());
    b.Paint();
    b.SetColor(
new Green());
    b.Paint();

    b 
= new SmallBrush();
    b.SetColor(
new Red());
    b.Paint();
    b.SetColor(
new Blue());
    b.Paint();
    b.SetColor(
new Green());
    b.Paint();
  }

}
posted on 2004-11-22 14:32 吕震宇 阅读(7465) 评论(43)  编辑 收藏 所属分类: 设计模式随笔系列

评论

#1楼  2004-11-22 14:55 montaque      
hehe,a simple but meaningful example.
  回复  引用  查看    

#2楼  2004-11-22 15:28 jiangyu [未注册用户]
太棒了。
吕大哥,由于我现在的工作基本上都是与数据库打交道,所以有的时候只能屈就于数据库结构。
模式啊,思想挺好,但就是不会用,郁闷。
谢谢您的这些好东西。
  回复  引用    

#3楼  2004-11-22 16:04 Rickie      
Good example.
  回复  引用  查看    

#4楼  2004-11-22 17:43 大漠孤烟      
Good example.
  回复  引用  查看    

#5楼  2004-11-22 21:30 onekey      
通俗易懂,妙就一个字!
  回复  引用  查看    

#6楼  2004-11-23 00:04 小新0574      
不错,写得很好懂,有点国外技术作者的写作风格
  回复  引用  查看    

#7楼  2004-11-26 10:22 wayfarer      
老实说,我看了这篇文章,只有一个字可以表达我的仰慕之情,那就是:震宇兄,你真牛啊!

我还没有把文章看完,就迫不及待地将本文加入到精华区了。是否草率?不,一点也不,只是因为这个比喻实在是太棒了,用毛笔和蜡笔的区别,来描述Bridge模式,真是微妙微肖。根本不用看代码,你会立即体会到这种设计模式给程序设计带来的好处了。

真是好文章啊,佩服!
  回复  引用  查看    

#8楼  2004-11-26 10:45 jeseeqing      
震宇兄你的设计模式系列真的让我受益非浅呀!

在看你的文章的同时,真的很佩服震宇兄你的中文的功底.

希望看到你的更多的好文章!
  回复  引用  查看    

#9楼  2005-01-27 13:05 idior      
交流一下
http://www.cnblogs.com/idior/articles/97283.html
  回复  引用  查看    

太形象了!
  回复  引用    

#11楼  2005-03-30 12:41 Duiker      
很好,真的很喜欢
  回复  引用  查看    

#12楼  2005-04-29 17:49 仁渣      
想形容几句,却发现自己没有那个文采,等我去找金庸先
  回复  引用  查看    

#13楼  2005-06-29 09:14 cv222 [未注册用户]
恩, 不错, 这个范例给的好, 对bridge有个直观印象了, 谢谢吕震宇
  回复  引用    

#14楼  2005-08-29 11:38 neushi [未注册用户]
拜读了您的不少文章,但是好像关于主要23种设计模式还没有写全,不知道什么时候可以见到如Mediator、State等的文章,期待ing...
  回复  引用    

不错!多多益善。

  回复  引用    

#16楼  2005-10-15 13:48 水灵儿 [未注册用户]
woaizhegewenzhang
  回复  引用    

woaini laogong
  回复  引用    

#18楼  2005-11-01 17:51 ls0627 [未注册用户]
很形象,谢谢吕大哥了。
  回复  引用    

#19楼  2005-11-05 14:41 asp [未注册用户]
原来bridge模式就是这样的,谢谢~让我受益非浅
  回复  引用    

#20楼  2005-12-20 17:56 汪新厚      
谢谢,大道至简!!!期待吕兄的新作!!
  回复  引用  查看    

#21楼  2006-04-23 21:17 夏林 [未注册用户]
爱生活,爱吕哥
  回复  引用    

#22楼  2006-06-28 13:24 隨風.NET      
不去当作家 浪费了
  回复  引用  查看    

#23楼  2006-09-19 11:33 kingmu [未注册用户]
吕兄,你的毛笔和蜡笔的举例有很明显的差别,感觉不错.但个人感觉用它们不足以体现Bridge模式的精髓,因为Bridge pattern的Goal是通过抽象与实现的分离实现各自的变化和灵活的组合,Implement 一般是实现一组操作.Color在此表示implementor,感觉不是很清晰.
  回复  引用    

#24楼  2006-10-12 15:16 轻风 [未注册用户]
写的不错,感觉比调治解调器的那个好,可能是因为我才接触设计模式,太复杂的理解不了,谢谢!!学到好多东西!
  回复  引用    

#25楼  2007-01-22 20:12 afuture [未注册用户]
感觉比喻的有点问题。
蜡笔和毛笔中的颜色和大小通过抽象都应该是一个类的属性。呵呵
  回复  引用    

#26楼  2007-04-25 11:24 wangle [未注册用户]
说得太好了
  回复  引用    

#27楼  2007-07-21 20:34 天纯蓝      
通俗易懂.太棒了!!!让我想起了C#中的泛型.可以应用到实际当中.
  回复  引用  查看    

#28楼  2007-08-17 16:21 asong [未注册用户]
这个随笔系列中这一篇是最通俗绝妙的了
  回复  引用    

说的太棒了
  回复  引用    

#30楼  2007-11-06 15:05 jeamzhang [未注册用户]
例子很生动!!!
  回复  引用    

#31楼  2007-11-23 16:29 good [未注册用户]
good
  回复  引用    

写的真好,谢谢你
  回复  引用    

#33楼  2008-01-11 12:07 royi_e [未注册用户]
我最近有这样一个需求,需要做一个工资管理模块.里面有个功能是晋级的.
晋级的条件是动态的,写在数据库里的.比如可能的晋级条件有
1.至2008工作年限满30年,今年自动晋升一档次
2.在同一级别连续干2年,自动晋升一档次
3.在同一职务上干5年,自动提升该职务对应级别的一个级别(比如厅长可能对应4,5,6三个级别,如果是6级,则提升到5级);
....
条件很多,而且可能动态增删的.我想了想,有点象防火墙的控制访问列表.
我最开始想用修饰器模式,后来想了想,这个方式不行.因为晋级条件是动态的,而且数目众多.
我想问的问题是,设计到动态匹配时,采用什么模式好.
---------请大家指点迷津,我就要动手编码了,还是一片茫然.
  回复  引用    

#34楼  2008-01-15 23:26 ericyang [未注册用户]
39楼的,明显是个strategy模式
  回复  引用    

#35楼  2008-01-19 22:20 Weck      
例子是简单,可怎么灵活应用到实际编程中去,真的还需要深深体会
  回复  引用  查看    

#36楼  2008-06-06 13:18 Hiken [未注册用户]
吕兄,最近一直在拜读你的设计模式系列,多谢写出这么好的文章,例子很好,很生动...
  回复  引用    

#37楼  2008-09-12 10:24 解放前 [未注册用户]
佩服,精彩,多谢分享
  回复  引用    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2004-12-21 10:01 编辑过
"五向定位"职业成长路线公开课(上海、南京、大连)
Google站内搜索


相关链接: