理解Design Pattern

本文的目的是以最精炼的语言,理解什么是Design Pattern,为什么需要Design Pattern,和关于Design Pattern的争论。

什么是Design Pattern?

从字面上理解,Pattern,指的是解决常见问题的可重用的方案。Design,则限定了,这里的Pattern是为软件的设计服务的。因此,所谓Design Pattern,指的是解决常见的软件设计问题的可重用的方案,或者说解决方案的模板。

 

两点需要特别注意的是:

  1. 算法不是Design Pattern。
  2. Design Pattern是为Design服务的,而不是为具体的实现服务的。

说道什么是Design Pattern,不得不提起一本书:《Design Patterns: Elements of Reusable Object-Oriented Software》,俗称Gang of Four或者是GoF。为什么?因为这本书太有名了,有名到太多人从听说到自以为熟悉Design Pattern,都是通过它,甚至狭义地认为所谓Design Pattern,就是指的GoF中的23种Pattern。这真是一个相当大的误会了。同样的,很多人提到Design Pattern,必提到SOLID原则,其实也是误会,SOLID是面向对象设计的基本原则,并非Design Pattern的基本原则,只是因为GoF是面向对象的Design Pattern,所以GoF中的Pattern自然需要遵守面向对象的SOLID原则。

 

针对不同的软件开发领域,其实有许多前人总结的Pattern。例如:GoF其实属于典型的面向对象Design Pattern,是前人从面向对象的设计实践中,总结的一些典型的Pattern。另外,还有针对架构设计的Pattern针对企业集成的Pattern针对SOA的Pattern,等等。大大牛Martin Fowler维护了一个他个人感兴趣的不同开发领域的Deisng Pattern的Catalogs

 

Pattern只是针对不同的场景的一些可重用的方案,因此,无需崇拜甚至神话任何已有的Pattern。一但一个Pattern服务的问题场景发生了变化,则往往可能导致这个Pattern不再适用此场景,或者需要被修正。任何人也都可以发现和总结新的Pattern。

为什么需要Design Pattern?

应用Design Pattern主要的好处如下:

  • 降低设计成本 - 每一个Design Pattern是解决一个常见问题设计问题最佳实践,因此,对于相同的问题,我们就无需做重复的设计,只需要重用即可。
  • 降低设计风险 - 相对于未经实现证明的朴素的设计,Design Pattern作为来源于实践,并且已经被前人证明的最佳实践,无疑风险更小。
  • 降低讨论和交流的成本 - 对于软件设计专家之间对设计的交流,如果大家都理解同一个Design Pattern,则无需提供太多的设计细节,就能让对方理解一个设计,因此交流的成本大大降低。

关于Design Pattern的争论

Design Pattern是否影响性能?

一定程度上,可以说“是”。相对于直接、朴素的实现,Design Pattern为了获得一定的灵活性,往往会引入一些额外的层次,对于局部来说,客观上的确是占用更多的资源,或者影响一些性能。

但是,我们不能孤立的看问题。撇开那些有极至性能要求的应用,Design Pattern在局部引入的一点点性能损失,往往并非是不可接受的,且还要考虑到其带来的其他好处;而一个错误的或者不够灵活的设计更有可能造成程序整体的缺陷和瓶颈,并且往往补救的成本要高得多。

Design Pattern是否为了弥补具体语言描述能力的不足?

判断这个命题,要看这里的“Design Pattern”是泛指,还是特指。如果是特指,Design Pattern既然只是指一些可重用的方案模板,针对,一些本身就是来源于特定语言的编程实践来说,当然,未尝不能使这个命题成立。例如:Core J2EE Patterns

 

但是,对于更多的并非来源于具体语言的的Design Pattern,如GoF这样的面向对象设计的Design Pattern,它关注的是面向对象设计的基本原则和限制,和具体的语言没有任何关系,又何来“弥补具体语言描述能力的不足”之说呢?

 

posted @ 2010-08-02 20:23 Teddy's Knowledge Base Views(2352) Comments(26) Edit 收藏

 回复 引用 查看   
#1楼2010-08-02 21:29 | 亚历山大同志      
一般来说Design Pattern前头还是要加上一个限定性的词才能够妥当的用于描述。广义上来说 解决常见的软件设计问题的可重用的方案 这个定义是没有办法为 Design Pattern著书立说的,因为包含太广容易闪了舌头。软件设计的范围何其广泛,我等穷一生之力也只能管窥其全豹一斑,面向对象的Design Pattern,函数式编程的Design Pattern(据老赵说有之,姑且以有论之,等回头研究研究再来说说这个问题),面向方面的Design Pattern,多核计算的Design Pattern,分布式的Design Pattern......
当一个概念包含太广其实也就失去了专注讨论的意义。换句话说就是这个概念被架空了。所以我们必须落到实处来讨论,否则各自天马行空收不住缰绳,讨论也就落到空处了。

 回复 引用 查看   
#2楼2010-08-02 21:31 | 亚历山大同志      
不过讨论是必要的,争论也是有益的,不讨论不争论那来的交流呢
 回复 引用 查看   
#3楼2010-08-02 22:00 | 徐培华      
这些文章都不知道你在说啥。
 回复 引用 查看   
#4楼2010-08-02 22:00 | 徐培华      
这些字面上的文章数不胜数。

 回复 引用 查看   
#5楼[楼主]2010-08-02 22:04 | Teddy's Knowledge Base      
@亚历山大同志
你说的没错。我担心的是现在很多人,尤其是初学者,对于Design Pattern的认识被误导了,认为其只是GoF,而且奉为圣经,从而影响了他们更全面、理智的看待Pattern,更一定程度上被扼杀了创新能力。

 回复 引用 查看   
#6楼[楼主]2010-08-02 22:23 | Teddy's Knowledge Base      
@徐培华
不知道你说的“字面上的文章”是何意?又不知你说的“这些文章”,又是指哪些文章?恕我愚钝,你的评论我也是真的不知道你在说啥。

我写文章,至少从来都是非常认真的总结和分享自己的经验,不是自己觉得理解的东西从不会拿来误导人。如有任何意见和建议欢迎一起讨论。

 回复 引用 查看   
#7楼2010-08-02 22:26 | Galactica      
@Teddy's Knowledge Base

你又误导人,知道周芷若为啥选择练《九阴白骨爪》,而不选择练《九阴真经》吗》?因为后者可以速成;知道欧阳锋为啥选择练《九阴真经》,而不选择练《九阴白骨爪》吗》?因为他想做武林至尊。

 回复 引用 查看   
#8楼[楼主]2010-08-02 22:34 | Teddy's Knowledge Base      
@Galactica
你这个推论我还真无语了~~

 回复 引用 查看   
#9楼2010-08-02 22:52 | 水言木      
顶!以前刚开始接触OOP时把Design Pattern看得跟神一样,后来也慢慢地开始认识到,它不就是和它的字面解释一个意思么,只是一些Pattern,核心还是OOP本身~~嘿嘿
 回复 引用 查看   
#10楼2010-08-02 23:10 | eract      
赞一个。GOF写的设计模式太过书面语言,不容易懂~因此,我看的是Headfirst的《设计模式》,以及Alan Shalloway的《设计模式解析》,其中有一点,使我印象深刻,就是在设计类的时候,一个比较重要的原则就是,类是有生命的东西,应该按照类的职责来封装方法。
 回复 引用 查看   
#11楼2010-08-03 08:56 | msnweb      
看了你的文章 我更加不理解了。 你把深奥的概念说得更加深奥了。
orz.

设计模式就是一些典型环境的典型设计方案。

类似于牛顿第一定律 第二定律。 合适的环境套用这个公式就可以了。
但是请记住牛顿定律也不是万能的。

设计模式是一些常用的思想,但它不是神更不是万能药。找合适的场合用用就可以了。


 回复 引用 查看   
#12楼2010-08-03 09:44 | 生鱼片      
design pattern只是对常见问题的一般解决方案,它并不是什么圣经类的东西,使用它必须 要先理解其深刻的内涵,之后你就可以忘记它,当你在遇到问题时你给出的解决方案自然就是各种模式的产物了。
 回复 引用 查看   
#13楼2010-08-03 10:07 | LanceZhang      
现在谈到Design Pattern,恐怕一多半人就直接跟GOF23联系起来了,觉得pattern是个好东西,潜意识的能用必用。但很多情况下patterns并不能直接被套用,就算能够部分套用,也要考虑各方面的成本,和是否真的有应用此模式的必要。

如果能用则用,为了让代码结构“优雅一点”便滥用只能造成OVER DESIGN——到头来重构起来更麻烦,还不如不design。

支持微软的叫法:Patterns & Practice

 回复 引用 查看   
#14楼2010-08-03 10:11 | LanceZhang      
想要实现 Galactica 所说的《九阴真经》,还不如看看《反面模式》,速成、让人少犯错误、不误导。

反面模式
http://zh.wikipedia.org/zh-cn/%E5%8F%8D%E9%9D%A2%E6%A8%A1%E5%BC%8F

 回复 引用 查看   
#15楼2010-08-03 11:27 | Clark Zheng      
我觉得写得不错
 回复 引用 查看   
#16楼[楼主]2010-08-03 12:02 | Teddy's Knowledge Base      
@msnweb
抽象的概念的确没有具体的实例来的容易理解,但是往往正是没有理解Design Pattern的本质,才造成觉得Design Pattern深奥.

 回复 引用 查看   
#17楼2010-08-03 12:20 | 钧梓昊逑      
知道周芷若为啥选择练《九阴白骨爪》,而不选择练《九阴真经》吗》?因为后者可以速成;知道欧阳锋为啥选择练《九阴真经》,而不选择练《九阴白骨爪》吗》?因为他想做武林至尊。

这个强

 回复 引用 查看   
#18楼2010-08-03 13:15 | Tony Qu      
老马最近写作热情很高啊
 回复 引用 查看   
#19楼2010-08-03 15:07 | msnweb      
引用Teddy's Knowledge Base:
@msnweb
抽象的概念的确没有具体的实例来的容易理解,但是往往正是没有理解Design Pattern的本质,才造成觉得Design Pattern深奥.

我更愿意相信 是描述的刻意抽象造成了新手的理解困难。不知道是表达能力还是描述角度问题,很多简单的理论总会被描述得非常复杂。就像设计模式。
而国外很多书,描述得却是非常细致,行语非常简单,理论很清晰。这才是实质,这才是本质。

 回复 引用 查看   
#20楼[楼主]2010-08-03 15:20 | Teddy's Knowledge Base      
@msnweb
可能还是我的表达能力不太好吧~~ 一个好的布道者,的确应该既对技术有深刻的理解,还要是一个好的作家,甚至是一个好的哲学家。

 回复 引用 查看   
#21楼2010-08-03 16:47 | Tristan G      
生病了还在家写博客........
 回复 引用 查看   
#22楼2010-08-03 16:51 | Tristan G      
大家都推崇GOF的书,其实我觉得GOF那书对于初学者来说看了可能会晕,不知道是不是翻译的问题,可能是我太愚钝了,我的设计模式启蒙是从Java与模式开始的
 回复 引用 查看   
#23楼[楼主]2010-08-03 17:20 | Teddy's Knowledge Base      
@Tristan G
卧床在家,没别的事可做,只能写写博客了~~

没错,在我看来GoF也是给设计师看的.junior或者middle级别的dev,如果我面试,能完善地写出singleton,我觉得已经能接受了.不过很遗憾,即使综合能力达到middle的dev,singleton能写出一个能编译的,可能只占六成,能考虑到线程安全的,顶多1成.

 回复 引用 查看   
#24楼2010-08-03 17:52 | 浪子      
引用Teddy's Knowledge Base:
@msnweb
可能还是我的表达能力不太好吧~~ 一个好的布道者,的确应该既对技术有深刻的理解,还要是一个好的作家,甚至是一个好的哲学家。


可惜现在国内大部分流行“实用”主义、理论无用论,觉得这些都是虚的,没用。其实理论指导才是最根本的。

所以讨论“理论”层面的东西的时候,好多人都开始“喷X” ^_^...

引用生鱼片:design pattern只是对常见问题的一般解决方案,它并不是什么圣经类的东西,使用它必须 要先理解其深刻的内涵,之后你就可以忘记它,当你在遇到问题时你给出的解决方案自然就是各种模式的产物了。

认可,只有忘记了,才真的理解了,因为你已经转化为经验,转化为自己的东西。

一开始看书,看代码,只是入门的方式。


 回复 引用 查看   
#25楼[楼主]2010-08-03 20:09 | Teddy's Knowledge Base      
@LanceZhang
"要考虑各方面的成本,和是否真的有应用此模式的必要"
--你说的没错,事实上over design还算好的,至少还是解决了问题,别人也还能理解,也还能重构回来;最怕就是盲目套用,把本来能说明白的东西,弄得说不明白了,到头来迟早要用大得多的成本来反工.

 回复 引用 查看   
#26楼2010-08-03 23:50 | FantasySoft      
Teddy兄,注意身体啊!

说说文章吧,文字很精练,赞!不过对于最后一点,我倒是有点不赞同,我觉得有些模式确实在某种程度上弥补了语言表达能力的不足。因为Java没了指针,那么相应的函数指针也没了,尽管更容易写出健壮的程序,但这是以损失灵活性为代价的。那么,设计模式是不是一种补救手段呢?