第一章 设计模式与J2EE技术
什么是设计模式
简单地说,模式是一个出现在世界上的实物,同时也是一条规则,告诉你应该如何创建一个实物、应该在何时创建。它既是过程,也是实物;既是对当前实物的描述,也是对创建实物的过程的描述。――C.Alexander,《建筑的永恒之道》[i]
在软件科学中,模式有很多种,有软件的管理模式,实践证明与传统管理是有区别的,从而是一种新的模式。有软件分析模式[cx1] ,有软件设计模式[cx2] ,过程模式[cx3] ,有软件重构模式等等。
软件科学中的模式到底是什么呢,能完全借用C.Alexander定义的模式吗?有人说软件跟建筑天生相像,你瞧 Architecture,身兼数重意思。其实GOF书中已经有说明:本质上一样。但是具体到软件领域又有所不同。可惜的是由于软件模式理论一直在发展中,公认的定义到目前为止还没有。但是确有几种经典的说法。有说,模式就是情境中一个问题经过证实地一个方案.这种定义比较简单,简洁明了。在Gof(Gang of four)的书中模式被定义成三段值:表示特定情境、问题、与方案之间的关系。并按照这样的方式描述介绍了著名的23种模式(c++语言描述)[cx4] 。在《J2EE core Patterns》一书种作者也作了类似的定义:模式是用来描述所交流的问题及其解决方案。并用类似于GOF书中的介绍步骤[cx5] [A6] 解析了15个J2EE模式[cx7] 。[A8]其他介绍模式的书籍、论文与网站也有自己的模式定义。但都推崇GOF书中的定义,并一般以其为蓝本对比介绍。
对模式本原的认识
软件中的模式起源于建筑[cx9] ,但是正如Gang of Four在《设[A10] 计模式》中所说:尽管Alexander所指的是城市和建筑模式,但他的思想也同样适用于面向对象设计模式。只是在面向对象的解决方案里,我们用对象和接口代替了墙壁和门窗。两者的核心都在于提供了相关问题的解决方案。
实际上我们生活在一个充满模式的世界里——当然,简单的而肯定的前提是我们的世界是有秩序的。现代的人除了疯子和变态,几乎都穿有衣服;大部分人都是一天吃三顿饭,当然也有一天吃两顿的;社会中,我们属于某个社区或团体,参与政治、经济活动;在我们参与的所有活动中,我们都按照一定的规则行事;在规则边缘的人们又总是希望加入规则使用者的行列,就像我们中国先前一直坚持入世一样。吃饭、穿衣、睡觉是我们人类基本的生活要求;我们每一个人都必须遵守,一个人如果不穿衣、不吃饭那没有其他结论,他根本就不属于人类。参与社区,在一定的框架下进行社会经济活动则是人类得以日益发展的内在要求。
其实在中国传统里头更是讲究模式,比如京剧,一招一式都有套路;再如中国画格式讲究套路,树该怎么画,有几种画法;又如《孙子兵法》——它可以说已经成为用在各方面“战争”的通用模式了,他告诉你在什么军事环境中采取什么阵法,然而怎么去拼打就靠自己的理解和灵活应用了。因而,创建模式的是大师级别的人物,拘泥于这些模式的人却只能叫做工匠。当然对于无所谓模式者,要么已经融会贯通,要么就是无知,他们应该首先成为的是工匠。就像我们中国,现阶段,就是在积极参与国际社会与经济活动规则的制定,用中华民族的传统美德和智慧重塑具有中华民族特色的国际、国内社会经济交往方式,再造适合于全体人类持续发展的社会经济活动规则。
为什么学习和研究设计模式
那么我们在软件中为什么要学习模式?模式到底给我们带来了什么好处而使得如此多人对它热衷?其实道理是一样的——我们都需要借鉴大师的经验,站在巨人的肩膀上才能够更好的前行。尤其在工科领域,这点显的更是重要。其次,学习模式能让我们学习和开发软件时少走弯路,使得我们的学习从一开始就是严密的。开发出来的软件也能更加scalable和reusable,从而可以提供更强的可维护性、更短的开发生命周期。知道模式,研究模式还可以让我们开发软件更流畅、更模块化,减少耦合。用一个术语说就是减少内应力,合理疏解软件的内应力可以使得软件系统长存。如建筑结构中分解压力一般,如果结构不合理,压力分解不均,建筑很可能很快就漏塌。使得新建筑/新软件在一定时期内不漏不塌就是我们要学习模式的基本原因;能够使得我们的建筑/软件长久甚至永存,正是模式如此吸引我们的魅力所在。
如何学习和研究设计模式
同样有必要从建筑中模式发展历程讲起,我们来看看Christopher Alexander教授“三步曲” :
•研究模式的理论——《建筑的永恒之道》
•第一个完整的模式语言——《建筑模式语言》
•理性地用模式来指导建筑过程——《俄勒冈实验》
本文要是有关设计模式的研究。设计模式第一次是由架构设计师 Christopher Alexander 在他所著的 A Pattern Language: Towns, Buildings, Construction(Oxford University Press,1977)一书中提到的。他引入了这一概念,并称为模式 — 对于反复出现设计问题的抽象解决方案 ――― 这一概念吸引了其它领域中一些研究人员的注意,特别是二十世纪八十年代中后期,那些开发面向对象的软件人员。
值得注意的是对软件设计模式的研究造就了一本据信是面向对象设计方面最有影响的书籍:Design Patterns: Elements of Reusable Object-Oriented Software(即后述《设计模式》一书),由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 合著。这几位作者常被称为“四人组(Gang of Four)”,很多人也戏称是“四人帮”,而这本书也就被称为“四人组/帮(或 GoF)”书。
在此经典模式理论指导下,就可以管窥设计模式的精要了。通常的步骤应该是:首先要了解设计模式,大凡接近她的人都会被她的魅力感召。这样就过渡到再次:系统学习设计模式,在学习的同时和学习以后我们要作的就是在项目中去实践设计模式了。必须指出的是最终实践设计模式时候要落实到具体的环境中,使用某种语言,受限于特定环境的应用需要勇气和变通,纸上谈兵是无助于实际的。本文是在J2EE环境中模式的分析与实践。
J2EE与模式
J2EE技术
现代软件逐渐流行起来的研究方法首先必从所谓体系结构看起。这种看法颇有道理:从整体着眼可以看得清楚、有居高临下的感觉,不但看得远,而且可以看得清晰。看得清楚意指一个东西,不如J2EE,他里面到底有那些东西,有了体系结构图,可以一目了然。所谓看得远,可以从体系结构中看开去,能够从体系上自然与其他技术体系比较,看出这种体系的优点体现在哪里、缺点又表现在哪里、今后发展的方向应该在哪里;所谓看得清晰,意指可以看到一个体系结构中各种元素彼此之间的交错众和、文理经脉能够一目了然,比清楚又进了一层。所以无论是初学者,还是资深的体系架构师,他们有一个共同特点就是一定喜欢看体系结构图。J2EE首先是个有机的整体,她以J2SE为基础,包含13种主要技术[A11] ,请看其结构图:
上面可以看到J2EE平台的整体结构,他的大部分核心技术也有标明:JDBC, EJB, RMI, JSP, JAVA SERVLETS, XML, JMS, JTS, JTA, JAVAMAIL 和 JAF。其实J2EE本质上由一整套服务(SERVICES)、应用程序接口(APIS)和协议构成,它对开发基于WEB的多层应用提供了功能支持。J2EE还要求描述在何时、何处需要使用这些技术。当然,知道这些不同的技术之间是如何交互的是理解J2EE而必须的。
过去,二层化应用 -- 通常被称为CLIENT/SERVER应用 -- 是大家谈论的最多的。在很多情况下,服务器提供的唯一服务就是数据库服务。在这种解决方案中,客户端程序负责数据访问、实现业务逻辑、用合适的样式显示结果、弹出预设的用户界面、接受用户输入等。CLIENT/SERVER结构通常在第一次部署的时候比较容易,但难于升级或改进,而且经常基于某种专有的协议—通常是某种数据库协议。它使得重用业务逻辑和界面逻辑非常困难。更重要的是,在WEB时代,二层化应用通常不能体现出很好的伸缩性,因而很难适应INTERNET的要求。
SUN设计J2EE的部分起因就是想解决二层化结构的缺陷。于是,J2EE定义了一套标准来简化N层企业级应用的开发。它定义了一套标准化的组件,并为这些组件提供了完整的服务。J2EE还自动为应用程序处理了很多实现细节,如安全、多线程等。
用J2EE开发N层应用包括将二层化结构中的不同层面切分成许多层。一个N层化应用A能够为以下的每种服务提供一个分开的层:
显示:在一个典型的WEB应用中,客户端机器上运行的浏览器负责实现用户界面。当然终端类型可以多种多样[A12] 。
表示层: 尽管浏览器可以完成某些动态内容显示,但为了兼容不同的浏览器,这些动态生成工作应该放在WEB服务器端进行,使用JSP、SERVLETS,或者XML(可扩展标记语言)和(可扩展样式表语言)。
业务层:业务逻辑适合用SESSION EJBS(后面将介绍)来实现。
数据访问:数据访问适合用ENTITY EJBS(后面将介绍)和JDBC来实现。 同后台系统的集成可能需要用到许多不同的技术,至于何种最佳需要根据后台系统的特征而定。
为什么有这么多的层?事实上,多层方式可以使企业级应用具有很强的伸缩性,它允许每层专注于特定的角色。例如,让WEB服务器负责提供页面,应用服务器处理应用逻辑,而数据库服务器提供数据库服务。
由于J2EE建立在JAVA2平台标准版(J2SE)的基础上,所以具备了J2SE的所有优点和功能。包括“编写一次,到处可用”的可移植性、通过JDBC访问数据库、同原有企业资源进行交互的CORBA技术,以及一个经过验证的安全模型。在这些基础上,J2EE又增加了对EJB(企业级JAVA组件)、JAVA SERVLETS、JAVA服务器页面(JSPS)和XML技术的支持。
有了上面的介绍,如果不纠缠于细节技术的实现(这样才有架构师的气魄),脑子里应该就有了如下的J2EE体系结构图:所有实现J2EE规范的Application Server都必须完成完全的web Container与EJB Container功能。有关Application Server 的选择和比较在[A13] 下文有更详细的介绍。
用模式的眼光看J2EE技术(IMPORTANT)
在学习了Java后学习J2EE,一般人都会有这样的感觉:入门很容易,但是要向前进一步似乎像赶鸭子上架,很难。原因在哪里?本质上说,是没有理解J2EE,不知道他里面到底体现了什么,仅仅知道他的组成部分虽然是必须的,但是却不是足够的。我们需要用一种全新的眼光来审视这种祥和的技术,可以这么说,本质上J2EE是一种模式架构,一种框架软件。他不同于我们学习的Java语言,我们在学习Java语言时候用的是API,那是工具箱。而J2EE不同,它的应用领域是一开始就定义好了的,所谓Java Two Enterprise Edition,就是说让Java用于企业领域。既然领域定好了,它就自然可以定义一套在这一领域不变的架构。如它定义了JTA、JDBC和EJB可以用来处理企业的事务要求、大量的数据库操作需求等。企业一般要用到邮件订阅、消息处理,可以使用J2EE技术里有机结合的JMS,企业安全性要求比较高,J2EE提供系统的安全解决方案,它定义了JAAS等。实际上,各种技术是一个整体并且可伸缩,每个J2EE应用都是按照其体系结构提供有机的J2EE技术组装。例如表示层技术典型的可以用JSP作配件,非典型的可以用WAP[ii]作配件,不管怎样他们都是J2EE的脸面;业务层技术典型的可以是EJB,非典型的可以是servlet甚至JSP,这些才是业务处理逻辑的核心技术,往往安全性等要求很高;资源层连接典型的是JDBC,非典型的用JDBC-ODBC等。从上面可以看到,J2EE在设计上就是框架结构导向的技术――只不过这种框架结构有极强的伸缩性和可扩展性。框架结构意味着一种思想的实现,大的方面J2EE广泛应用于企业计算,据信国外1998年后出现的门户大多采用J2EE技术。广义上J2EE还是MVC的一种实现。上图中客户端得到View,中间层是Controller,后台则是Model[iii]。所以,在企业应用这种情境下,J2EE可以采取不同的适合情境应用的解决方案(使用各种套件)。不变的东西已经定义好了,变化的则交由程序员来处理。有人也许会想起.Net,实际上她也是一套框架结构,不过可以说成是“超级(抄袭)模式”应用框架结构:-)。
下面我们用模式的眼光来审视J2EE[A14] 用用
架构的特点(注意并不是每个框架都有这样的特点的,J2EE灵活性做到了最大):
首先,灵活性。灵活性意指这种结构或模式是不依赖于任何实际应用,应该与操作系统、应用程序无关。提供独立的结构,可以提供最大的重用。
其次,可扩展性。新技术的发展是很快的。试想一个基于现有J2EE技术的应用,如果哪天JDO[iv]被引入规范,这种应用还是基于“J2EE”的吗?即J2EE的扩展会不会影响已有的应用的问题。可扩展性的应用架构是不会影响已有的应用的。J2EE的分层实现思想提供了各种技术的平滑过渡。
再次,可伸缩性。对于集群应用,这种功能要求体系的一览无余。迄今为止,除了在操作系统级集群能作的比较好外,在应用级恐怕只有J2EE能够很好的做到这一点了。
然后,可配置性。应用本身是变化的,因为需求随着人员的调用、业务的增长在不断变化。这样在配置应用时就需要有一定的灵活性。例如资源的访问控制,以前只有少许几个WEB资源,可以提供给大多数人访问;随着业务的扩展,新的业务不断增加,业务逻辑自然增加,这种资源的控制就需要一套灵活的机制来做调配。在J2EE中XML文件可以提供这种灵活的控制。
最后,安全性。进来由于网络环境的改善,网络应用呈爆炸式增长。在网络上一个基本的问题就是安全。一个安全的应用应该提供统一的用户访问控制即提供单入口点。J2EE天生为网络环境而诞生。J2EE模式中前端控制器等可以实现要求的安全控制。
J2EE设计模式
detailed infomation please ref: http://java.sun.com/blueprints/corej2eepatterns/Patterns/index.html
在项目中使用模式
模式的好处之一是让你从系统的高度分析,理解自己和别人的代码,在设计代码中获得提升自己的机会。
另外用模式的思想来设计系统会自然出现许多优点:可以获得系统设计的灵感,设计自己的框架甚至系统,现在已经有很多组织和个人在做这方面的工作,比如Struts等。可喜的是国内也出现了类似的组织。使得自己的系统更具有安全性,灵活性,可维护性——提到的每一点都能为你在更短的生命周期中开发出更多、更好的应用。
反过来说,如果你没有系统的模式思想,不用模式思想来设计系统,那很可能就会在设计自己的系统时挂一漏万,出现漏洞。下面是一个挂一漏万的例子:
[v]可以看到这是个内部网页,他是基于J2EE技术的一个应用,后台服务器是BEA WebLogic Server。按照安全性等要求应该只有登陆用户(而不是注册用户更不是任何用户)可以访问并使用,否则会带来垃圾信息甚至其他安全问题。所以在每个子页面应该有个安全控制机制。控制的方法是在访问的每个页面添加认证模块,这样可以保证每次页面访问的时候做一个简单的SESSION判断。如果具备J2EE设计模式的思想,解决这个问题一点也不难:前端控制器模式是个不错的选折。然而遗憾的是,任何知道绝对域名的人员和自动化程序都可以毫无保留的访问这个网页,并作一些不允许的操作[vi]并且这些操作毫无约束。[vii]
[i] ,引自《设计模式》
[ii] ,目前,基于J2EE的WAP应用开发一般先开发JSP和HTML。这样作的目的是调试相对方便
[iii] ,关于MVC的更详细介绍,在第三章“MVC模式”一节
[iv] ,JDO提供了访问数据库的能力,可以代替实体EJB使用
[v] ,如果是电子文档,可以看到演示,否则请看文字介绍。
[vi] ,不允许的操作,毫无约束指什么,访问过的人都会知道,作为一个公益门户网站,还是给他留一点颜面吧。
[vii] ,更遗憾的在已经得到不安全的警告后的几乎几个月里,在写这篇论文的时候,该网站还没有采取必要的保护行动。
网站:
[cx1]描述可复用分析模型,如交易、度量、会计和组织关系。更多信息可参见《Analysis Patterns:Reusable Object Models》
[cx2]最重要的模式。通常是面向对象的,描述系统设计、组件交互和特定语言模式。是本论文的重点。
[cx3]描述软件过程设计。
[cx4]网友提供Delphi版本、c#版本,java版本
[cx5]环境-问题域-作用力-解决方案
[A6]步骤是什么,作个底注也好
[cx7]模式目录是不断发展的,在Sun Java Center中讨论、定型和发布
[A8]在本文中有相应描述,应该作个联结去
[cx9]阎宏博士在《Java与模式》一书中表达了不同的观点。H:/&_毕业设计/模式基础/模式参考(网文)/www.javaresearch.org/article/showarticle.jsp-column=31&thread=3572.htm
[A10]找出原文,作个引用
[A11]作个脚注
[A12]可以作参见:那篇CSDN上的cx099介绍终端设备的文章
[A13]回头整合到一篇文章中时作个联结
[A14]图形需要编号