引言
在软件开发过程中,一个系统成败的关键就是在于其设计,如果系统设计的很好,那么在后续开发中就能少走弯路,并且在后续的系统维护中,能够简单、轻松,但如果系统设计中就出现了问题,那么这个系统的开发必然是痛苦的,编程人员的不停抱怨,维护人员的痛苦挣扎,最终导致系统的报废,没有人愿意再去关注它。
因此,人们非常希望能够在新的软件开发过程中使用那些在软件系统设计、开发过程中长期积累的很多好的、有价值的经验,来提高新系统的开发效率,保证新系统能够稳定、安全、易于维护。
所以,如何将这些有价值的经验记录下来,能够很好的交流、传递就显得非常重要。对这些直接的、原始的经验,采用面向对象的方法进行抽象,提炼出很多的模式,这些模式很清晰的说明了它们所表达的关联、问题和解决方式之间的关系。而这些在软件设计上积累、抽象出来的模式,我们称之为设计模式。
设计模式的概念
简单地说,模式是一个出现在世界上的实物,同时也是一条规则,告诉你应该如何创建一个实物、应该在何时创建。它既是过程,也是实物;既是对当前实物的描述,也是对创建实物的过程的描述。我们需要这样一种语言:它让我们高效地交流、讨论那些常见的、重复出现的设计概念,并在这些概念上建立起我们的系统。不要仅仅把模式当作解决方案,而要把它们当作设计的词汇,这些词汇可以根据一定的规则组合起来形成句子(也就是系统设计)。
C. Alexander描述:“每个模式是一个有三个部分的规则,它表达一定的关联、一个问题和一个解决方式之间的关系。”
设计模式可以使人们更加方便的复用成功的设计和体系结构。将已证实的技术表述成设计模式也会使新系统的开发者更加容易理解其设计思路。设计模式帮助你做出有利于系统间潜在联系的说明规范,设计模式甚至能够提高已有系统的文档管理和系统维护的有效性。简而言之,设计模式可以帮助设计者更快更好的完成系统设计。
设计模式的分类
在《设计模式》书中共给出了二十三个模式。这二十三又根据其表现不同可分成了几类。各个模式是在不同场景下,不同问题的解决方案。
创建型模式
创建型模式抽象了实例化过程。它们帮助一个系统独立于如何创建、组合和表示它的那些对象。一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象。
随着系统演化得越来越依赖于对象复合而不是类继承,创建型模式变得更为重要。当这种情况发生时,重心从对一组固定行为得硬编码转移为定义一个较小的基本行为集,这些行为可以被组合成任意数目的更为复杂的行为。这样创建有特定行为的对象要求的不仅仅是实例化一个类。
创建型模式中有两个不断出现的主旋律。第一,它们都将关于该系统使用哪些具体的类的信息封装起来。第二,它们隐藏了这些类的实例是如何被创建和放在一起的。整个系统关于这些对象所知道的是由抽象类所定义的接口。因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以及何时创建这些方面给予你很大的灵活性。它们允许你使用结构和功能差别很大的“产品”对象配置一个系统。配置可以是静态的(即在编译时指定),也可以是动态的(在运行时)。
结构型模式
结构型模式涉及到如何组合类和对象以获得更大的结构。结构型模式采用继承机制来组合接口或实现。一个简单的例子是采用多重继承方法将两个以上的类组合成一个类,结果这个类包含了所有父类的性质。这一模式尤其有助于多个独立开发的类库协同工作。
结构型对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而实现新功能的一些方法。因为可以在运行时刻改变对象组合关系,所以对象组合方式具有更大的灵活性,而这种机制用静态类组合是不可能实现的。
行为模式
行为模式涉及到算法和对象间职责的分配。行为模式不仅描述对象或类的模式,还描述它们之间的通信模式。这些模式刻画了在运行时难以跟踪的复杂的控制流。它们将你的注意力从控制流转移到对象间的联系方式上来。
行为类模式使用继承机制在类间分派行为。本章包括两个这样的模式。
行为对象模式使用对象复合而不是继承。一些行为对象模式描述了一组对等的对象怎样相互协作以完成其中任一个对象都无法单独完成的任务。这里一个重要的问题是对等的对象如何了解对方。对等对象可以保持显式的对对方的引用,但那会增加它们的耦合度。在极端的情况下,每一个对象都要了解所有其他的对象。
从设计模式中得到的收获
设计模式是系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计,其目标是将设计经验以人们能够有效利用的形式记录下来。设计模式使人们可以更加简单方便地复用成功地设计和体系结构。将已证实的技术表述成设计模式也会使新系统开发者更加容易理解其设计思路。设计模式帮助你做出有利于系统复用的选择,避免设计损害了系统复用性。通过提供一个显示类和对象作用关系以及它们之间潜在联系的说明规范,设计模式甚至能够提高已有系统的文档管理和系统维护的有效性。简而言之,设计模式可以帮助设计者更快更好地完成系统设计。
模式的绝大多数好处都来自于原封不动的使用,也就是说,没有任何形式的外部支持,这带来了四大好处:
1. 它们记录了专家的经验,并且让非专家也能理解。
2. 它们的名称构成了一份词汇表,帮助开发者更好的交流。
3. 它们帮助人们更快的理解一个系统,只要这个系统是用模式的方式描述的。
4. 它们使系统的重组变得更容易,不管原来的系统是否以模式的方式设计的。
第一项显然是模式最大的好处,但第二项也同样重要,试想在一个开发项目的过程中,包括口头的和电子的,有多少字节的信息在开发者之间流动,由于有如此之大的信息交流量,所以效率上任何微小的提升都能大量节约时间。在这个意义上,模式拓宽了人们交流的带宽。对于第三、四条的评价,也越来越显著,特别是在项目越来越大、软件生存周期越来越长的今天。
当然,至少在短期内,模式主要存在于大脑中,而不存在于工具中。如果有了方法学或自动化工具的支持,应该还有其他的收益。
应用设计模式时存在的问题
显然,设计模式为我们的软件开发提供了非常有价值的经验和方法。同时,也为我们提供了一个有价值的思路,就是将我们自己的经验总结成模式来交流。但与此同时,对于模式的理解和使用,也存在着许多问题。
对模式的误解主要有三类:首先是对于“ 模式是什么” 的误解, 其次是对于“ 模式可以做什么” 的误解, 最后是对于支持模式的人群的误解。
模式是什么?如果对模式的概念简化,就是“模式是某种场景下某个问题的解决方案”,但这个说法是不完全的,因为忽略的模式的几个重要因素:
1. 可重复性:解决方案应该对应于外部的场景,这个场景是会重复发生的。
2. 可传授性:一个解决方案应该可以移植到问题的不同情况上( 绝大多数模式的可传授性都建立在“约束”和“效果”的基础上)。
3. 准确的命名:用来表示这个模式的名称,因为模式既是一个事物, 也是对类似事物的描述。
可重复性定义了这个场景是会多次出现的,因此我们需要多次面对,并解决同样的问题。可传授性则定义这个经验是有必要的传授的。而准确的命名则是模式描述准确性及其交流时的重要保证,虽然,术语的定义很可能是白费力气,因为一个定义可能对一个人(比如程序员)有意义,但是对另一个人(比如只能看到书面材料的项目主管)却毫无意义。所以,任何对模式要素的规定,除了必须包括问题、解决方案和场景之外,都必须提及可重复性、可传授性和名称。
那么模式可以做什么?“模式可以保证软件的复用性、更高的生产力……”
道理很简单,模式什么都不保证。它们甚至有可能无法给你带来利益。在创造新事物的过程中,模式无法取代人的位置。它们只是带来一种希望,有可能让一个缺乏经验的、甚至是未入门的,但是有能力、有创造性的人尽快获得设计的能力。
人们经常说:好的模式会让读者有“啊!”的回应。实际上,只有当模式恰好拨动了读者的某一根心弦时,他们才会有这样的反应。如果没有,模式就只像森林里普通的一棵树。因此,什么是好的模式?不管它写得有多好,如果不能引起读者的共鸣,它又怎能算是好的模式?模式只是开发者的工具箱中的另一件工具,对模式寄以过高的期望只会适得其反。准备充分,然后做最坏的打算——这就是防止受骗、消除对抗最好的方法。
“模式可以‘生成’整个软件体系”
每过一段时间,模式论坛上就会讨论一次模式的生成能力。按照我的理解,“生成能力”是指模式创建最终行为的能力。很多人认为,模式可以帮助读者解决模式本身没有明确提出的问题。我读过的一些书里也有同样的观点。
对于我来说,“生成能力”的关键是模式的可传授性——约束及其解决,或者对于效果的讨论。在你定义、精炼一个体系结构时,这些观察是特别有用的。但是模式本身并不制造任何东西——任何东西都是由人来制造的。而且,模式不可能覆盖体系结构的每个方面。给我任何一个有实际价值的设计,我都能找出其中模式没有涉及的设计问题。也许这些问题不常见、不具可重复性,或者只是还没有以模式的形式记录下来。不管怎样,你都必须负责填补模式之间的空白——用你自己的创造性。
“模式是针对(面向对象)设计或实现的”
另一个极端则是过分的限制,就象这个误解。坦白说,任何人都完全可能相信它,我不会有丝毫惊讶。无数的人问过我这个问题,所以它也进入了“十大误解”之列。如果你觉得这种观点实在天真幼稚,跳过这一部分吧。
如果模式不能记述专家的经验,那它们就什么都不是。对于模式的作者来说,任何形式的专家经验
都是可记载的。当然,在面向对象软件设计中有值得记载的经验,但是在非面向对象设计和分析、维护、测试、文档、组织结构……这些方面也同样有值得记载的经验。现在,不同领域中的模式开始浮出水面。
至少已经有两本关于分析模式的书[Fowler97, Hay96],并且每次PLoP 大会都会收到新的模式类型。(特别有趣的是1996 年的PLoP 大会甚至关注了音乐作曲的模式!)
和大多数的误解一样,这个误解也是有原因的。看看人们用来描述模式的格式,有两种基本的风格:
描述高层结构的GoF 风格(用于《设计模式》中);接近文学的Christopher Alexander 风格——叙述性的,尽量少的结构图。由于已经用模式描述了面向对象设计之外的东西,所以我现在认识到GoF 风格
造成的偏差。对于我研究过的某些领域的专家经验,这种风格根本无法描述。为什么结构图看上去总是让人联想到C++?对于音乐作曲的模式,“实现”应该是什么?“协作”部分真的有意义吗?
很明显,一种格式不能适应所有的需求。比较具有普遍意义的是模式的概念:模式是记载并传达专家经验的工具——不论是哪个领域的专家经验。
对于支持模式的人群的误解
“模式社群是精英的小圈子”
我很想知道这种观念到底是从哪里来的。如果说模式社群的人们有什么引人注目的地方,那就是他们之间巨大的差异。从PLoP 大会的与会者名单就能看出,人们来自世界各地,有大公司的也有小公司的,有分析员、设计者和实现者,有学生也有教授,有大名鼎鼎的作者也有初出茅庐的菜鸟。更让我惊讶的是,竟然有不少与会者都不是计算机科学工作者!这个社群仍然在不停变化,每年的与会者名单都与前一年不同。
如果将模式社群的背景公开出来,别人也许会觉得奇怪:很少有学院派人士。实际上,绝大多数PLoP的与会者都是实践者。软件模式早期的推崇者,包括Kent Beck、Peter Coad 和Ward Cunningham,都没有学院背景。GoF 中只有一个人(Ralph)是学院派,而且他也是我所认识的最实际的学院派。很明显,模式社群从根本上反对任何可能的宗派主义和精英论。
文章来源于领测软件测试网 https://www.ltesting.net/