Chinaunix首页 | 论坛 | 博客
  • 博客访问: 330786
  • 博文数量: 76
  • 博客积分: 8291
  • 博客等级: 中将
  • 技术积分: 1540
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-22 10:13
文章分类

全部博文(76)

文章存档

2009年(1)

2008年(75)

我的朋友

分类: Java

2008-03-05 08:55:25

第一部分
作者:Bill Venners
2005年5月23日
概述
设计模式在设计者中是一种流行的思考设计问题的方法.但什么是思考设计模式的适当方法呢 在本次访谈中,Erich Gamma,经典巨作《设计模式》的合著者,与Bill Venners就思考和使用设计模式的正确方法展开对话.
1995 年,Erich Gamma作为畅销书《设计模式:可复用面向对象软件的基础》的合著者蜚声软件界.这本经典巨著,通常也称为GoF系列,收集了23个一般设计问题的特定 解决方案.1998年,他跟Kent Beck一起开发JUnit这一Java社团中事实标准的单元测试工具.目前,Gamma是IBM位于瑞士苏黎世OTI实验室的杰出工程师.他引领 Eclipse社团,并负责Eclipse平台的Java开发工作.
2004年10月27日,Bell Venners在加拿大范库弗峰举办的OOPSLA会议上碰到了Erich Gamma.在这次访谈中,将在Artima开发者的Leading-Edge Java栏目中分期发布,Gamma提出了软件设计方面的独到见解.在这里,Gamma在正确地思考和使用设计模式的方法上提出了他的观点,并阐述了不同 模式库之间的区别,比如GoF和Alexander的模式语言之间的区别.
设计模式的真实价值
Bill Venners(B):我和Bruce Eckel在教设计课程.我们发现人们确实想知道GoF模式.经常有些模式的研讨会.围绕设计模式有很多市场宣传.
Erich Gamma(E):10年以后也会如此么
B:是的.人们想知道模式.我想绝大部分是因为模式还是一个热门词汇.我想拨开云雾去发现您认为热门到底应该如何对待模式.对待模式的态度应该是什么 人们怎么使用模式才能更好地工作 模式的真实价值是什么
E:我想模式作为一个整体能够帮助人们学习面向对象的思维:如何利用多态性,设计合成,代理,平衡职责以及提供可插入式行为等.模式远超出了用图形化方式代表对象以及类继承和多态.当理解了模式才真正学习多态.因此模式有利于学习面向对象和基本设计.
在 此基础上,每一个单独的模式有不同的特征,以方便提供更多的柔性或者封装抽象或者减少耦合.这在大系统中是个大课题.如何保护层级 如何避免回调和循环依赖 GoF模式用最少的工具在这些问题上提供帮助.不依靠人为的方案而是通过解释各种权衡来实现这一点.尽管模式是从具体使用中抽象出来的,但也提供了有价值 的实现线索.在我看来,正是因为模式是可实现的才使得其有如此大的价值.
模式是从专家经验中提取出来的.因此你可以重复别人的成功设计.你可以站在专家的肩膀上做设计,而不必重新发明"轮子".但是模式有很多实现差异,所以还必须时刻留意.最后,模式提供的设计积木的名称也只是一个描述和讨论一个特定设计的词汇表.
其他问题包括如何教模式.尽管不知道你具体是怎么做的,但我想不应该是设立一个课程并只是枚举那23个模式.这种方法不会带来任何东西.你必须感觉到有问题的设计所带来的痛苦.我猜一旦感受到这种设计痛苦你才会感激模式.
B:什么痛苦
E: 比如你的设计不够柔性,一个简单的改变就会波及整个系统,而你则必须复制代码或者代码变得更多更复杂.如果在这种凌乱的情况下你适时采用了一个模式,那么 将发现:痛苦没有了,你也感觉好多了.眼前豁然开朗:就是这个模式,工厂模式或者策略模式,是这个问题的解决方案.我想这是一种很有趣的教学方法.
刚 开始教模式的时候确实很无聊,因为只是简单地枚举每一个模式.当努力用真实例子展示如何使用模式的时候真的是非常有趣.换句话说,你需要在真实的环境中展 现问题――人为的例子行不通.在OOPSLA上我收到一个本名为《Heads First Design Patterns》的书.这是本好书,不仅仅是因其可读性,更在于其用小说的方式以高可视的形式对设计模式精要进行沟通.
B:这么说模式的价值就是在现实世界中当感觉某种痛苦时就可以找到某种已知的解决方案
E: 这也是我极力推荐给那些使用模式的人的方法.不要一开始的时候就把模式塞到设计中,随着工作的进展并对问题越来越理解的情况下使用模式.只有这样才会在如 实采用模式,再分解模式.我曾经在一个新闻组里看见过一条发言:在模式刚刚流行起来的时候有人要求在一个特定的程序里采用所有的23个GoF模式.他们失 败了,因为他们只用了20个.他们希望客户能够再找他们回来以便他们能够用上另3个模式.
试图用所有的模式是件坏事,因为最后会落下一个人为的设 计――没有人需要投机性设计出来的柔性.当前软件太复杂了.我们不能容忍去推测其他的应该怎么样.我们需要切实关注那些需要的部分.这也就是为什么我喜欢 对模型再分解.人们应该学会当他们有了一个特定的问题或糟糕代码的时候,就象人们现在所表达的那样,就能去他们的模式工具库里去发现解决方案.
B: 很有趣,因为第二个问题是:我观察到经常人们觉得使用最多模式的设计就是最好的.在我们的设计研讨会上,我让一些人参与一个设计项目,并在研讨会结束时向 其他人进行展示.这些展示者几乎总是想说明在他们的设计中使用了多少个模式,尽管我努力告诉他们目标是一个清晰的,易于理解的API,而不是去赢一场使用 最多模式的比赛.我刚听你说了同样的事情:那不是正确思考模式的方式.那么,在设计中使用模式需要做哪些恰当的调整呢
E:很多模式都是关于可 扩展性和可复用性的.如果确实需要可扩展性,那么模式会提供给你一个相应的方法,这很好.但是当你不需要可扩展性的时候,就应该让你的设计保持简单并且不 增加不必要的间接层.Eclipse的一个座右铭是在需要的地方提供可扩展性.事实上,如果你对我们在Eclipse里如何使用模式感兴趣的话,我在 《Contributing to Eclipse》的某一章节中试图描述模式的应用情况.在那章中我用设计模式解释了Eclipse架构的某些方面.
B:对于可扩展性你的意思是
E:意味着你可以定制化行为而不用涉及现存的代码――这是一个经典的面向对象主题.你可以根据你的特定问题复用某些东西.
设计模式的核心抽象
B: 在一篇你与Kent Beck合写的名为"JUnit:A Cook's Tour"文章中,你们与读者分享了整个JUnit设计.在文章中你们说:"直到有了整个系统的架构后才一个接一个的采用模式,但在开始的时候什么都没有 ".我想这个方法也许是受到Christopher Alexander的启发,他在建筑模式上的工作启发了软件模式运动.你觉得在一个模式上再叠加另一个模式直到完成为止是一种有效的设计方法么
E: 这篇文章是综合的.实际上在做JUnit的时候我们重构了整个设计.我们不是按照模式驱动的方法来开发JUnit,而是按照严格的测试驱动的方法来开发 的.针对一个测试在JUnit中确实有一个核心抽象,并且围绕这个核心抽象形成了依次被多个模式实例实现的多个其他设计点.在其他成熟的设计中也可以发现 这一点.你经常会看见几个关键抽象作为设计核心,并围绕这些关键抽象你可以实现各种不同的东西.模式就是从这些设计核心中成长起来的.但是我并不用这个来 作为质量标准.
B:这就是你通常所说的"模式密度"
E:是的,模式就是从一些核心抽象中形成的.
B:你说过在JUnit中TestCase是核心抽象.
E:事实上是由TestCase实现的Test接口是核心抽象,当然我们是从TestCase开始并从那里进行扩展的.
B:那么你能否定义密度呢 到底在其中有多少个模式 你说过那篇文章也是综合的.
E:在某种意义上这个综合是当你剥离分析完在我们测试驱动的开发中所发生的所有测试活动之后才能看见.因此这是一个非常扁平的表述.所呈现的模式密度都是围绕Test接口来的.
当 我们设计JUnit的时候不是把模式排列在一起.我们是按照测试驱动的方式来开发的:刚开始的时候就是一个能够成功执行的测试;一旦通过,我们才想怎样才 能改善代码.以测试驱动的方法开发一个测试框架不是没有相应的挑战,但一旦有了那些基本工作之后开发起来就出奇的顺畅.当然,我跟Kent在设计 JUnit的时候对模式非常熟悉.因此,我们经常说"嘿,这是一个合成模式"等诸如此类的话.在JUnit中用到了合成模式.我们也用到了模板方法.那是 最基本的一个.当然,还有命令模式.这也是一个关键模式.我们从测试开始,老是说:"噢,这是一个命令模式;哦,这是一个模板模式"等等.因为我们对模式 很熟悉,所以我们之间的交流也很快,以便进行高速设计.
这正好说明了模式是如何提供给我们设计词汇表的.同样的,当你看UML图时有很多方框和箭 头,但这些东西不会告诉你这些关系背后的意思.但一旦知道了相关模式,它就会解释清楚这些关系到底是什么.如果是观察者模式,为什么这两个类之间有一个关 联就很清楚了.因为那是一个家伙观察另一个家伙.你也会清楚的知道后面会是什么.我想这才是关键点.模式给我们一种谈论设计的语言.事实上,JUnit的 开发旅程并没有结束――我跟Kent目前正在开发JUnit4.0.我们会继续以测试驱动的方法来发展JUnit.其中主题之一是降低进入门槛.为此我们 正利用J2SE 5.0象注解之类的新特性来使得JUnit更易于使用.
模式语言
B:从C. Alexander的角度来说,什么是模式语言
E: Alexander有一个非常雄心勃勃的目标就是创建一个提高生活质量的建筑架构.为此Alexander开发了一种模式语言.这是一套建立在相互基础上 的模式集合.模式语言指导设计者在整个设计中如何应用各个模式.当我们开始涉足设计模式时可没有那么雄心勃勃.我们经常使用的是一种基于微架构的自底向上 的方法.
B:自底向上
E:退一步来看我当初是怎么涉及模式的.我想这会回答你的问题.我跟Andre Weinand一起合作开发过一个全面的C++类库和框架ET++.当我反省ET++的时候,一个成熟的框架显然应该包含提供诸如可扩展,解耦等特性的甚 至是优雅的循环设计结构.这样的结构就可以认为是有利于建立一个全面系统架构的微架构.在我的论文里我最后总结了一打甚至更多个这样的微架构.这样得出的 模式应该跟模式语言是有区别的:不是一上来就是一套自顶向下的相互交错的模式集合,微架构是一些更独立的模式,直到最后才以自底向上的方式相互联系起来. 尽管我们只有有限的工程材料和工程知识,但模式语言可以指导你完成整个设计.我承认我们的做法不那么雄心勃勃,但这仍然是重要的而且是有用的.
B:模式语言是否象一种与上下文无关的语法,并从中可以创建一整套程序
E: 在某种抽象层面上是有一些相似之处的.就象一种语法可以定义一整套程序一样,一种模式语言可以产生一整套方案.Christopher Alexander说他的模式描述了一个方案,这样即使在不大相同的情况下也可以被采用很多次.但对我来说,到了这样的程度公共部分就没了.
B:他是怎么定义"产生"的 假如我有上下文无关的语法,也不会产生程序.我还是需要去写.
E: 你还必须要作出决策.但是一种模式语言可以提供给你更多的指导,而且还有一些流程.比如你想设计一个你觉得舒适的房间.他会说,先在两边安上灯.好的,现 在你在两边安上了灯,那下一步做什么呢 你怎么放置窗户呢 针对这个问题有其他的模式来描述一个方案.基本上他会在整个空间上指导你.这种联系将我们在GoF书中描述的模式库与模式语言区分开来.我们发现那些微架 构也不是一些孤岛,他们是有联系的.我们在书封里将这些联系描述出来,这也是那些C. Alexander追捧者认为我们的书唯一有价值的地方.
B:这听上去象一个设计方法论.你按这个方法去做,做这个,做那个,最后得到一个漂亮的,居住舒适的房间.
E: 是的,依据Alexander的模式方法实际上就是按一定次序遵循特定模式.我们不规定一个特定的顺序.如果你有问题,我们有对应的方案,但我们没有下一 步.我们不会给你下一步该做什么的任何线索.在这方面,Alexander的做法更彻底.JUnit有点象这样的模式语言方法,因为它能帮你写一个测试用 例.在JUnit的文档中,我和Kent也写了一个关于如何实现一个测试的迷你模式语言.你以一个测试为开始,那么你要使用公共安装代码,并且把所以测试 进行分组等等.
阅读(470) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~