什么是 Design Pattern?许多人一讲到 Design Pattern,就会扯到什么建筑设计,因为他们全都是看四人帮的「Design Patterns」经典本的解释,没消化就照单全收。 如果不能用更生活化的方式解释 Design Pattern,我会怀疑他们是不是真的了解 Design Pattern 的真义。
什么是 Pattern
Pattern 最简单的定义是:只要是一再重复出现的事物,就是 Pattern。依照此定义,生活中就可以找到一堆 Pattern 的例子:
第四台广告中的 Pattern:
原价 ...,现在购买只要 ...,还送你一组 ...,请马上来电 ...,如忙线中请稍后再拨。
利用分割画面显示出使用前使用后的差别,来加强说服力。例如:由 C 升级到 E(注:C 和 E 不是指程序语言)。
找人现身说法:「杰瑞!感谢你介绍这套欧莱礼 Java 系列,让我在短短的三个月内成为公司内首屈一指的 Java 专家,这实在是太神奇了!」
选举时的 Pattern:
1. 质疑对手 A 钱或搞婚外情
2. 把家人通通拉上台痛哭一场以示选情告急
3. 开口唱「爱拼才会赢」
其它像是金光党的手法,刮刮乐诈财的技俩 ... 等,也都具有一再重复出现的特性,所以都可算是 Pattern。
电影中的 Pattern
电影中也有大量的 Pattern,请看下面的例子。
提高追杀时紧张程度的 Pattern
坏人追杀好人时,好人躲进车子,却发现车子发不动,引擎嘎嘎作响,一面努力地继续发动,一面念念有词「Come on, Come one」。
坏人追杀好人时,好人冲进电梯,死命地押着 close 按钮,脱口而出「Come on, Come one」。
许多电影都会使用上述两个 Pattern,虽然是老掉牙的 Pattern,但每次看到这里,总是让我紧张得心脏病差点发作,我不得不承认这两个 Pattern 实在是挺有效的。
增加主角杀死坏人合理性的 Pattern
电影最后,坏人和好人大对决,最后好人胜利,但是好人如果直接把坏人宰了,那好人在观众心中的形象就会受损,所以好人先饶坏人一条生路,但是坏人却坏到骨子里了, 偷偷拿出一把枪瞄准好人,说时迟那时快,好人机警地察觉,为了自保于是将坏人一枪毙命。这个 Pattern 可以让好人有人性,又让坏人死有余辜。
床戏的 Pattern
不管和剧情有没有关系,编剧和导演总爱加上一段激情的床戏。这个 Pattern 相当困扰我和我的家人,因为每次看到这里,我们保守的一家人往往觉得很尴尬,我们所反应出来的 Pattern 是:借口倒茶水,上厕所,打电话 ... 而离座避风头 ... 但眼睛仍不时偷瞄。
恐怖片的 Pattern
无须我举例,电影惊声尖叫(Scream)第一集就为我们剖析出恐怖片的一大堆 Pattern。
公式化
好莱坞的电影比较多 Pattern,而欧洲的电影比较少 Pattern。至于昆丁塔伦提诺(Quentin Tarantino)编导的电影,完全是不按排理出牌,很难找到 Pattern。正因为好莱坞的电影很容易就可以找出 Pattern,所以常常会有似曾相似的感觉。许多人批评好莱坞的电影很「公式化」。
基本上,Pattern 就是一种公式化的表现。那么,究竟公式化是不是好事?
以艺术来说,公式化的结果会造成僵化,所以负面效果居多。电影号称是「第八艺术」,也是一种艺术创作,所以最好不要出现太多 Pattern,否则肯定被影评人痛批「了无新意」。
以工程来说,公式化是好事。这些公式都是「千锤百炼」的结果,运用这些公式可以确保工程具备一定的品质,并加快工程的进行。而软件开发也是一项工程,也需要尽量运用公式。 (软件另有需要艺术的一面,这不在本文的讨论范围)。
什么是 Design Pattern
所以,Pattern 就是一种「千锤百炼」的智能结晶。有经验的专家和没经验的新手,差别就在于:有经验的专家知道如何在适当的时机,套用某些公式(Pattern)以解决特定 的问题,这是专家经年累月所培养出来的 Know-How(请参见「软件产业的知识经济」一文)。
一般来说,对象导向软件开发的程序可以粗略分成 OOA(对象导向分析)、OOD(对象导向设计)、OOP(对象导向实作)。在 OOD(Object-Oriented Design)阶段所采用的 Pattern 就称为 Design Pattern。运用良好的 Design Pattern,可以使得系统架构更优良(也更快完成),对于后续的 OOP、测试、维护,都会有很大的 帮助。Design Pattern 会告诉你,什么情况下用 Delegation 而不要用继承、什么情况下用 Interface 而不要用 Class... 诸如此类的知识。这些都是软件界前辈的智能结晶。
我要强调 Design Pattern 专指 Design 时期的 Pattern。但是 Coding 时的 Pattern(例如程序代码内缩)最好不要称为 Pattern,以免混淆。Coding 时期的 Pattern 最好称为 Coding Style(或 Code Style)。
Design Pattern 这个名词也可沿用到许多地方。我认为孙子兵法就是一本军事领域 Design Pattern 的书,它告诉你什么时候该采什么样的军事动作。至于怎么去砍人,则是属于 implementation 的部分,不属于孙子兵法的范围。
什么是 Anti-Pattern
并非所有的 Pattern 都是好的,不好的 Pattern 称为 Anti-Pattern。如果你的系统中出现了 Anti-Pattern,就表示你犯了别人「常犯的典型错误」。简言之,Anti-Pattern 就是错误的示范,要尽量避免。
让 Design Pattern 成为你的不时之需
许多人在设计阶段才来喟叹:「 Pattern 到用时方恨少。」其实你可以避免这样的情况。现在市面上有许多本 Design Pattern 和 Anti-Pattern 的书。只要好好把这些书读过,体会每个 Pattern 的真正涵义,你可以在短短的时间内,功力激增一甲子。即使读过的 Design Pattern,如果比较少用,一阵子之后也可能会忘记。 所以最好能隔一阵子就把 Design Pattern 的书拿出来复习。