长空待击

« [读书笔记]敏捷软件开发-无法完全理解和... | Main | [读书笔记]敏捷软件开发-创新和沟通的合... »

http://blog.matrix.org.cn/xMatrix/date/20060325 星期六 2006年03月25日

[译文]对话Eric Gammar--模式与实践

摘要
在这次对话中,Erich Gamma讨论了设计模式是问题的解决方案,设计模式如何帮助理解其意图和权衡利弊及如何通过实践来成为更好的设计人员。

设计模式是问题的解决方案
Bill Venners: 我第一次深入理解OO编程是来自于阅读Scott Meyers的《Effective C++》。在那本书中有一准则说“要确信公共的继承模型是“是什么””,这句话使我真正理解了继承的含义。然而,另一条准则说“通过组合来为“拥有什么”或者“实现什么”建模”,但这一准则并没有使我更明白组合的用途。
然而在GoF书中我发现了更具体的使用组合的描述,如用组合来为如“适应什么”/“代理什么”/“装饰什么”建模。如果你看一下书中的UML图,会发现他们很类似。大部分都是通过接口继承来使用组合。模式的不同之处在于那些你尝试用组合和继承关系来解决问题。即使类图看起来类似,但其设计意图却不同。那么设计模式中代表意图的角色是什么呢?
Erich Gamma: 模式通常都对应于特定问题并且在一定的上下文中被使用。虽然不同的模式中的解决方案看起来可能类似,但他们解决的问题是不同的。实际上大量事实证明模式是通过增加中间层次来解决问题的。有趣的是这种中间层次是如何实现的及为什么需要。因此如果你只是看一下问题的解决方案,他可能并不是那么明显,所因为有的东西看起来都差不多。就像在我们写下设计模式时我们也常有这种感觉--他们好像都起源于策略模式。
开始的时候我们只描述解决方案,大概有20页的目录。有经验的开发人员理解起来也没什么问题而且反馈我们如“是的,我就是那样做的。”然而后来我们注意到很难找全所有的,因此我们给出不同的抽象,不同的代理,但最主要的还是寻找问题的解决方案。对模式的观点和前期读者的反馈使我们不再只关注于解决方案而且也注意起问题本身。模式包含一个问题和其解决方案,你需要两者都关注。例如,策略和状态模式有同样的解决方案:代理给分离的对象,然后使用对象类层次来适应行为变化的接口,但他们针对的问题是不同的。策略模式是用来插入算法,而状态是用来在类状态改变时改变相应的行为,就像一个状态机那样。

理解设计意图和权衡利弊
Bill Venners: 在GoF书,你说“理解这本书中的设计模式可以使你更容易理解现有的系统”。如何理解?
Erich Gamma: 你可以说包含模式的系统比较没有的更简洁。模式简化了设计的对话。我和Kent Beck在Eclipse书中的最后一节就是个好例子,我们描述了一些Eclispe的包含模式的设计,你可以看到是如何简洁的了。你可能会说“这是组合模式”,而不需要说更多,别人就知道是什么了。
有趣的是我们在Eclipse的早期版本中进行了这种模式分析,而分析结果对最新的版本依然有效。虽然结果已经过期但模式依然一致。
一旦你理解了系统是使用了一定集合的模式,而且你也了解这些模式的缺点,那么你就更容易理解使用这个解决方案的开发人员的意图了。模式不仅告诉了你其意图而且已经权衡了利弊。一旦你理解了设计的局限性,你就更容易成就一个可重用的设计如框架。而最坏的结果就是你与设计做对,这时你并没有实际理解设计,不只是其意图,而且可能你会说“我会用我的方式来做”。
Bill Venners: 你刚才说模式也告诉了我们利弊的权衡。这是什么意思?
Erich Gamma: 设计经常要权衡利弊,有很多可选方案而每一种方案都有自己的行为结果。在设计是通常需要做决定,每一个决定都有其优点及缺点。这也是我们从编写设计模式中学到的重要一课。开始时我们对模式都很兴奋,因为我们只看到正面的效果,直到有读者指出实际结果并不是这么美好。于是我们开始考虑另一面--模式的局限性。这时我们也认识到标识一个模式相对比实际使用一个模式更简单。举例来说:你增加了一个策略模式,然后有了更多的灵活性,但另一方面你使用了更多的对象和额外的中间层次。是吧?所有的事都是有代价的,这也是我说的利弊。模式的一个关键点在于他捕获这些利弊而你不再需要同样的分析了。在你遵循设计的流程时,模式会是一个路标。如果你继续下去,你也会理解其中的利弊。我认为这是非常有价值的。

应用设计模式
Bill Venners: 在书中你们说“知道这些设计模式可以使你成为更好的设计者”,如何理解?难道我不需要知道应用他们的时机吗?
Erich Gamma: 不,你还需要动用自己的思想。这并不是很明确什么时候来应用设计模式。此外,你也要知道模式在应用进的各种变化及如何也调整模式。你通常需要改变一个模式来适应特定的问题。
这里可能是对设计模式作一些坦白的时候,在书中我们只说了什么时候可以应用一个模式,但我们没有讨论什么时候删除一个模式。删除模式可以简化系统而且可能有一个简单的解决方案可以更好地解决问题。简单解决方案的出现可能是一个真正的挑战。
Bill Venners: 许多人想成为好的设计者,他们希望这本书帮助他达到目标,但只读这本书好像并不能。。。
Erich Gamma: 并不能成为好的设计者。这点我也同意。只通过阅读书籍来学习模式甚至设计并不能真正掌握他们。目前还有其他的好的模式的书籍,那么在看完GoF书后也可以参考了其他的。
Bill Venners: 那什么是成为好的设计者的因素呢?
Erich Gamma: 除了阅读书籍,还需要阅读和理解大量的代码,看一下现有的系统如何解决一个特定的问题及有经历的设计人员是如何做的。通常设计模式就是记录了有经验的人做过的东西。但只了解设计模式是不够的。你可以通过模仿优秀开发人员的工作来提高,如现在有许多开源的项目可以作为学习的范例,Eclipse也是其中一个。通常你对开源项目的捐献是被欣赏的。你不仅要学习成为设计人员,还要提出好的设计思想,还要沟通和讨论他们。你必须要实践,就像是一个刚上路的学徒,经过大量的实践你就会成为有经验的设计人员了。

实践,实践,还是实践
Bill Venners: 在书中你写到“很容易将模式看作一个解决方案,看作一个可以调整和重用的技术。但要看到何时何地将模式最好应用于特定的问题是很难的。”新手如何来理解呢?假设他们看完了书,也理解的模式,现在他们开始工作了,他们是该如何学习到何时使用一个模式是合适的,还是该成为一个“模式化”的设计人员尽力使用尽可能多的模式?
Erich Gamma: 不幸地是,许多事只有在实践后才能真正体会。如果我是一个新手,我最想有一个导师或者伙伴,我会和他们一起编程,然后导师会说“嘿,这个地方看起来有问题”或者“NND,你怎么又重复了一遍”。导师通常会提供即时的意见和帮助。这也是双人编程的优点,这是一种提高技术的有效方式。我经常从双人编程过程中学到东西而且我希望会学得更多。
当然底线是你需要通过编程来学习模式,而不只是过家家而已。你不可能从读书中学会模式,通过书你不可能完全掌握模式,只有你开始将模式应用到编程中的实际问题,你才会开始更好地理解模式并且为下一次提高作准备。

评论:

发表一条评论:
  • HTML语法: 启用

Valid HTML! Valid CSS!

This is a personal weblog, I do not speak for my employer.