设计模式的实际应用
 

2010-02-22 作者:Walter Hurst 来源:网络

 

通常,概念和这些概念在现实世界中的应用是有区别的,设计模式也不例外。

设计模式无处不在。在阅读技术方面的出版物或者浏览技术方面的网站时,很容易发现对设计模式的引用。到目前为止,您很可能已经阅读过(至少翻阅过)一些设计模式方面的书籍,如《Core J2EE Design Patterns》或者Gang of Four编写的《Design Patterns》。此时,您可能会对设计模式有一些疑问。设计模式如何帮助我?他们是银弹吗?使用设计模式有什么问题吗?为什么我不能从集成开发环境(integrated development environment,IDE)中获得设计模式?

上述的几个问题是采用设计模式进行处理过程中遇到的一些经典问题。通常,概念和这些概念在显示世界中的应用是有区别的,设计模式也不例外。本文将讨论设计模式在现实世界中的应用。这些信息可以帮助您成功地在项目中采用设计模式来作出正确的决定。

快速概述

设计模式提供了一种共享经验的方式,可以使团体受益和避免不断的重复发明。设计模式通常捕捉问题的描述、问题的语境、推荐的问题解决方案以及使用解决方案后可以预见到的结果。为了具有最广泛的适用性(从而对更多的读者有用),设计模式通常从取决于环境的精确细节中抽象而来。这种抽象性产生了一些把设计模式应用到现有的案例中所必需的译码。这是一个重要细节:尽管设计模式是共享专业知识的好方法,但通常它对正确应用专业知识是非常重要的。

设计模式这个概念最初产生于建筑行业。设计师(设计建筑物而不是计算机系统)意识到他们需要共享有关正确设计技术的想法。这些想法是在可以使设计师团体从分享经验和教训中获益的设计模式中形成的。设计模式在80年代后期从建筑业进入计算机系统领域。面向对象(Object-oriented,OO)原则逐渐得到普及,而设计模式成为培育新的OO追随者的最佳实践。

Richard Gamma等(人们通常把他们称作 Gang of Four [GoF] )编著的《Design Patterns: Elements of Reusable Object-Oriented Software》一书使设计模式成为万众瞩目的焦点。随着设计模式逐渐普及,他们所涉及的领域就像“Ben and Jerry”效应那样也逐渐广泛起来。对那些不熟悉著名冰淇淋品牌的人来说,Ben and Jerry是一家冰淇淋产品的供应商,其冰淇淋产品拥有各种可以想象得到的配料组合(还包括一些您永远想象不到的)。因此,它就是设计模式,和普通的OO设计模式一样来源于GoF的著作,但是现在包括了专为开发语言、应用服务器、行业合成等提供的设计模式。

设计模式分类

设计模式通常根据一些公共特性而组合在一起。GoF的著作把设计模式划分为三类:Creational、Behavioral和Structural。用于J2EE的设计模式通常划分为表现层(Presentation Tier)、业务逻辑层(Business Logic Tier)和集成层(Integration Tier)。这种分组方式可以使描述所有设计模式共享的公共细节更加轻松,或者使设计模式的分类和发现更加轻松。

在对设计模式实际应用的讨论中,需要把设计模式划分为两类:broad exposure和isolated use。这种划分基于设计模式对应用程序设计人员和开发人员的可见性和应用程序的多个部分对设计模式的相依性。

Broad exposure 设计模式因为可以影响多个团队成员或者应用程序的多个方面的设计和开发而闻名。这类设计模式的品质包括:

1.采用它会对很多根据设计模式创建的类产生负面影响。

2.应用程序的不同部分知道设计模式的使用。

3.使用这种设计模式的决定不能轻易取消。

这类设计模式的例子有Model-View-Controller(MVC)模式、Value Object J2EE模式和Data Access Object(DAO)J2EE模式

Isolated use是指设计模式的使用是隐藏细节的设计模式。这类设计模式的品质包括:

1.设计模式不影响其他团队成员或者应用程序其他部分的工作。

2.可以轻松地更改使用设计模式的决定,而且产生的影响极小。

这类设计模式的例子有Singleton GoF模式或者Intercepting Filter J2EE模式。

将设计模式划分为几类为了解设计模式的范围提供了一种快速的方法。了解范围使评估设计模式的影响更加轻松。可以使用或者抛弃这种设计模式吗?一旦采用这种设计模式就会影响应用程序的设计吗?这种设计模式影响了应用程序的多个部分和其他的应用程序了吗?预先了解这些影响为采用设计模式提供了指导。

设计模式应用AntiPatterns

随着设计模式逐渐普及,出现了另一种叫做AntiPatterns的模式类型。尽管设计模式提供了关于可重复的最佳方法的专业知识,但是AntiPatterns通常描述应当避免的重复行为。AntiPatterns 验证了这样的事实:做错事情和办对事情的人一样多。

本节将探讨设计模式采用中的AntiPatterns。了解这些AntiPatterns可以帮助您避免设计模式采用中的缺陷。如同设计模式一样,在他们提供了一些远见或者他们是一些非常熟悉的环境时,在他们可以为您的经验添加色彩和使您不再感到孤独时,此处的AntiPatterns是一个全新的概念。如果您想阅读更多有关AntiPatterns的资料,请参见本文结尾处的资源列表。

AntiPattern清单

设计模式?是的,我们全部拥有

问题:决定在项目中使用哪一种设计模式。

应用: 既有broad exposure又有isolated use设计模式。

环境:一位开发人员通过介绍希望在一项工程中使用设计模式。

动力:AntiPattern的动力通常有两种来源。一种是开发人员通过包括设计模式的最佳实践来改进项目的渴望。另一种是开发人员天生的好奇心驱使他利用这个项目来研究设计模式。

推荐的解决方案:项目中应用了所有知名的设计模式。设计模式手册生成一份清单,而目标是可以核对所有的设计模式。

产生的语境:项目团队和交付的应用程序由于不自然地引入太多设计模式而遭受损失。这就导致设计和开发非常复杂。这种不必要的复杂性会从已经完成的工作量、开发团队了解发生事情的能力、应用程序的实际性能和功能的正确性等方面影响开发成果。

设计基本原理:设计模式是专业知识的主要来源。尽管使用他们的效果很好,但是全部使用他们就未必也是好的。

实际解决方案:设计模式的描述包含了使用模式的目标语境。必须考虑如何确保设计模式匹配项目。第二,设计模式不是来源于当某人阅读了一本设计模式的著作后,问:“我可以把这个设计模式使用在什么地方?”而是来源于某人寻找已发现问题的解决方案。

Developer/Project AntiPattern的实现(也称为:Design pattern xyz? Yeah,我们有10个)

问题:在项目中或者项目之间控制设计模式的实现。

应用:broad exposure和isolated use设计模式都从解决这种环境中受益。但是,broad exposure设计模式无疑控制了实现。

语境:开发团队将设计模式结合到项目中。团队由许多经验丰富的开发人员组成,他们知道应该什么时候使用设计模式。所以会正确的设计模式。如果涉及到多个项目,项目之间没有设计模式实现共享。

动力:最终期限日益临近,团队成员工作效率很高。重新使用实现会影响团队效率。假设他们都是专家,他们的实现都非常优秀。在多项目情况中,跨团队通信和代码共享要么没有被考虑,要么被作为进度表中的潜在影响被排除。

推荐的解决方案:团队可以根据需要单独包含和实现设计模式。

产生的语境:即使使用了正确的设计模式,但是他们是以很多不同的方式实现的。在限制集成和重新使用成果的实现之间存在不兼容。很多不必要的时间和工作被花费在维护、调试和扩展各种实现上。最终,各种实现都将被统一。

设计基本原理:应当允许专家成员独立工作。只要所包含的设计模式足够好,就不需要共享实现。

实际解决方案:开发团队应当协调设计模式的使用。共享设计模式的公共实现可在将来降低成本,但是更重要的是,它使开发人员之间互相兼容。如果需要,这种共享可以被限制到划归先前讨论的broad exposure设计模式内。重用实现在项目间也极有价值,尤其在未来将要集成的时候。

设计模式采用中IDE的角色

IDE在继续发展和提供更多的功能。最初的IDE组成了一种编辑环境和一些调试工具。现在,他们通常包含设计环境、审计工具、配置管理系统集成等等。随着IDE不断扩展范围,需要确认他们在设计模式实现中的角色。诚然,设计模式在开发语言中实现,而IDE可以用于编辑源代码。但是,IDE可以扮演其他的角色吗?

一些IDE具有下拉菜单,使您能够选择应用程序中包括的设计模式。虽然这可以加快设计模式的使用,但是它只会导致更快地编写出极差的代码。评估这个特性需要记住几个因素。

第一,设计模式在抽象中描述问题,并需要一些译码来达到正确的实现。但是,他们常常包含“示例实现(sample implementation)”,并且IDE正是将这种示例类结构插入到应用程序中。这很可能不是所需要的实现,并且把他们放到应用程序中将带来更多的困惑,以及需要更多的编辑和重构工作而不是思考最初的实现。

第二,和IDE拖放设计模式方法有关的另一个问题是前面讨论的两种AntiPatterns。加快设计模式的实现很可能会产生大量的设计模式应用,以及同一设计模式的多种版本,而不是解决任意问题的版本。

设计模式面临的挑战不仅仅是得到一次快速实现,而是确定使用了正确的实现,以及机构中已有的一个完美的实现。

BEA WebLogic Workshop 8.1和设计模式

您可能是一位BEA的客户,如果您正在阅读本文,您可能想知道新的BEA WebLogic Workshop 8.1是如何影响您的设计模式考虑的。首先,WebLogic Workshop是IDE,因此前面有关IDE的章节同样适用。对这些讨论感兴趣的Workshop的两个额外方面是控件和预实现的设计模式。

WebLogic Workshop Controls是打包功能的一种方法,可以轻松将其包含到使用Workshop IDE的应用程序中。打包包括IDE必需的可视元素、运行时行为、要求的配置等等。控件是如何影响设计模式应用的呢?还记得设计模式在前面划分为isolated use和broad exposure吗?划分到isolated use类的设计模式可能被打包成 Workshop Controls。把设计模式作为控件打包可使 Workshop IDE的其他用户共享实现,从而避免了每一个Developer/Project AntiPattern中的实现。

您可能想知道为什么broad exposure设计模式为什么不可以作为控件实现。原因是broad exposure设计模式导致创建了许多其他类或者独立于其他应用程序。这种情况就不适合控件的即插即用方面。broad exposure设计模式的采用应当三思而后行,一旦采用就不能轻易取消。这些要求不符合WebLogic Workshop Control的目标。

WebLogic Workshop还具有很多预实现设计模式,如Pageflow和用户接口结构。在Workshop 中,您可以创建JSP和定义Pageflow来控制Web应用程序页面之间的定位。在这种情况下,WebLogic Workshop使用流行的Apache Struts 表现层框架。Workshop的这个方面(使用 Struts)提供了一种Model-View-Controller(MVC)设计模式实现,意味着不用创建自己的MVC实现。Workshop包含的其他功能很可能替代您自己的设计模式实现。尽管一些设计模式实现的开盒即用很好,但是应当验证不仅实现而且实现创建的WebLogic任何依从性也非常合适。

成功采用设计模式的三个步骤

如何把设计模式的采用和日益临近的最后期限、紧缩的预算和很多公司现有的有限团队资源相结合?以下是成功制订设计模式的三个步骤。

强大的通信和培训

许多机构拥有领先技术,可能正式通过了设计师论坛的论证或者非正式的公认专家。这些领先厂商将推广设计模式采用中的开放通信,并将培训开发具体设计模式的团队。通信应当跨开发团队和项目以便预先防止采用竖井和多种惟一的实现(谨记每个Developer/Project AntiPattern的实现)。培训可以采用正式的internal lunch-and-learns、正式的internal class或者派一些员工参加外部培训。这些培训方式将促进正确的设计模式应用程序。如果仅有极少的观众能够参加培训,最佳的候选人是那些感觉适合在回来后能够培训其同事的人。

设计模式采用指导

设计模式可用于使项目受益,但是他们也可能因为误用而对应用程序造成损害。应当鼓励采用他们,但是对其的采用应当受到审阅和验证。设计模式可以包含在设计和开发过程中。在任何一种情况中,设计模式的使用应当由审阅者确认和验证。在审阅过程中还可能会遇到这样的情况,额外的设计模式不适用于最初包括的地方。即使环境中没有进行正式的审阅,这一步骤也可以通过同事审阅或者团队讨论来完成。这一步骤中的审阅者要么是主要团队的成员,要么与他们建立开放通信。

指导采用对于broad exposure类别的设计模式非常关键。这些设计模式具有很多相关的风险,因为他们将创建依赖性。这些依赖性可能在一些对象类中,例如,只工作在更加广泛的DAO设计模式实现范围中的数据访问对象(DAO)、或者跨应用程序边界(如使用Value Object设计模式在应用程序和应用程序层之间传输数据)。这些设计模式也可以由项目中的其他人或者不同项目的人实现,而且实现应当重新使用,不同于创建另一种独特的实现。

重用实现,不只是设计模式

只要在创建自己的设计模式实现中有一定的满足,团队和公司就可以在重用发生在代码层时,而不是设计创意层时获得更多益处。使企业获益的最初设计模式是改进的实现。但是,真正的目标是重用实现。重用实现将导致:a)其他可重用的类(取决于公共实现);b)缩短开发时间和降低成本;c)缩短维护时间和降低成本;d)在应用程序之间和内部轻松集成。

这种重用对broad exposure设计模式非常重要(有时是基本的)。这些设计模式创建了外部依赖性(集成将从公共实现中受益)或者产生全部的自定义类库(如果有公共基础将可重用)。isolated use设计模式也可以从重用中获益,但是如果他们是根据具体情况定制的,他们就非常难以重用。

有时您可能会问自己:“如果重用比较好,为什么设计模式和可以重用的实现不可以一同应用呢?”在我们讨论设计模式如何使更多读者获益的时候才会讨论这个问题。如果可能,如果已经预定义了实现,那么达到广泛适用性这个目标就会非常困难。然而,一旦设计模式被应用到特殊的问题域或者技术基础设施中,那么就可以重用在该环境中产生的实现。

架构中的设计模式

这看起来像是一件可怕的任务,需要掌握设计模式如何应用在实际情况中,如何构建优质的实现,以及如何促进重用实现。完成该任务的方法之一就是在环境中引入应用程序架构。应用程序架构提供了应用程序需要的结构,从而使开发团队可以关注应用程序的域逻辑。这包含了已实现的设计模式。除了重用设计模式概念或者单个实现之外,可以在多个项目和应用程序之间重用架构。这种共享的公共实现确保了兼容性,并为开发和维护多种不同的实现提供了一种低成本替代方案。兼容性提供了重新使用需要的技术基础。没有足够的篇幅在这里深入讨论架构的其他重要品质,如运行时监测和管理、可配置应用程序逻辑和适应性行为等。您可以从Carnegie Mellon Software Engineering Institute (www.sei.cmu.edu/ata/ata_init.html) 中学习到更多有关架构的知识。

结束语

设计模式是一种令人惊异的资源,应该使用他以增加您的优势。虽然设计模式提供了可重用的概念,但是面临的挑战是决定使用哪一种设计模式和致力于可以重用的实现。通过了解采用设计模式中会产生的风险,就可以在继续学习和实现更多设计模式时避免风险。按照本文概述的步骤会产生一个流程,用于在团队和机构中推广成功的设计模式采用。


火龙果软件/UML软件工程组织致力于提高您的软件工程实践能力,我们不断地吸取业界的宝贵经验,向您提供经过数百家企业验证的有效的工程技术实践经验,同时关注最新的理论进展,帮助您“领跑您所在行业的软件世界”。
资源网站: UML软件工程组织