﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-彷徨－－－向左走，向右走-随笔分类-Java Study</title><link>http://www.blogjava.net/wkling100/category/3700.html</link><description>敢问技术之路再何方？
</description><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 18:33:58 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 18:33:58 GMT</pubDate><ttl>60</ttl><item><title>Laszlo简介</title><link>http://www.blogjava.net/wkling100/archive/2006/04/17/41422.html</link><dc:creator>将星泪</dc:creator><author>将星泪</author><pubDate>Mon, 17 Apr 2006 01:59:00 GMT</pubDate><guid>http://www.blogjava.net/wkling100/archive/2006/04/17/41422.html</guid><wfw:comment>http://www.blogjava.net/wkling100/comments/41422.html</wfw:comment><comments>http://www.blogjava.net/wkling100/archive/2006/04/17/41422.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wkling100/comments/commentRss/41422.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wkling100/services/trackbacks/41422.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Laszlo</span>
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">是在<span lang="EN-US">WWW</span>环境中开发及发布<span lang="EN-US"><a href="http://www.cnblogs.com/dannyr/"><a title="" href="http://www.cnblogs.com/dannyr/">RIA</a></a></span>应用系统的源代码开发平台，遵循<span lang="EN-US">OSI</span>认证的<span lang="EN-US">CPL</span>许可<span lang="EN-US">(<a href="http://www.opensource.org/licenses/cpl.php"><font color="#0000ff">Common Public License</font></a>)<?XML:NAMESPACE PREFIX = O /?><o:p></o:p></span></span>
				<br />
				<br />
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Laszlo</span>
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">平台由<span lang="EN-US">LZX</span>语言和<span lang="EN-US">Laszlo</span>展示层服务器组成。<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<ul type="disc">
				<li class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto">
						<span lang="EN-US" style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">LZX</span>
						<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">语言是一个<span lang="EN-US">XML</span>和<span lang="EN-US">JavaScript</span>描述语言组合，本质上类似<span lang="EN-US">XUL</span>和<span lang="EN-US">XAML</span>。<span lang="EN-US">LZX</span>使用声明性的和基于文本的开发步骤，支持快速原型法和最佳软件开发实践。<span lang="EN-US"><o:p></o:p></span></span>
				</li>
				<li class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto">
						<span lang="EN-US" style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">Laszlo</span>
						<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">展示层服务器<span lang="EN-US">(LPS)</span>是一个<span lang="EN-US">Java Servlet</span>，将<span lang="EN-US">LZX</span>应用程序编译为目标运行环境的可执行代码。<span lang="EN-US">Laszlo</span>当前的运行环境目标为<span lang="EN-US"><a href="http://www.cnblogs.com/dannyr/"><a title="" href="http://www.cnblogs.com/dannyr/">flash</a></a></span>播放器，<span lang="EN-US">LPS</span>将<span lang="EN-US">LZX</span>应用程序编译为<span lang="EN-US"><a href="http://www.cnblogs.com/dannyr/"><a title="" href="http://www.cnblogs.com/dannyr/">flash</a></a></span>播放器的<span lang="EN-US">SWF</span>字节代码，为任何嵌入<span lang="EN-US">Flash5</span>播放器或更高版本的<span lang="EN-US">Web</span>浏览器提供已编译过的应用程序的代码和缓存，并且可以为应用程序代理请求后台的<span lang="EN-US">XML</span>数据和<span lang="EN-US">Web</span>服务。<span lang="EN-US"><o:p></o:p></span></span>
				</li>
		</ul>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align="left">
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">         <img height="300" hspace="5" src="http://dannyr.cnblogs.com/images/cnblogs_com/dannyr/lzx_screen.gif" width="400" align="center" /><br />使用<span lang="EN-US">Laszlo</span>你将可以：<span lang="EN-US"><o:p></o:p></span></span>
		</p>
		<ul type="disc">
				<li class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-list: l1 level1 lfo2; tab-stops: list 36.0pt; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto">
						<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">使用基于<span lang="EN-US">XML</span>和<span lang="EN-US">JavaScript</span>的标准<span lang="EN-US"><a href="http://www.cnblogs.com/dannyr/"><a title="" href="http://www.cnblogs.com/dannyr/">RIA</a></a></span>应用<span lang="EN-US"><o:p></o:p></span></span>
				</li>
				<li class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-list: l1 level1 lfo2; tab-stops: list 36.0pt; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto">
						<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">可以将应用部署到任何运行在<span lang="EN-US">Linux</span>、<span lang="EN-US">Unix</span>、<span lang="EN-US">Windows</span>或者<span lang="EN-US">Mac OS X</span>上的<span lang="EN-US">J2EE</span>应用服务器或<span lang="EN-US">Java Servlet</span>容器中。<span lang="EN-US"><o:p></o:p></span></span>
				</li>
				<li class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-list: l1 level1 lfo2; tab-stops: list 36.0pt; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto">
						<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">可以将应用展示在拥有<span lang="EN-US">97%</span>桌面<span lang="EN-US">Web</span>浏览客户端的<span lang="EN-US"><a href="http://www.cnblogs.com/dannyr/"><a title="" href="http://www.cnblogs.com/dannyr/">flash</a></a> 5</span>播放器或更高版本中<span lang="EN-US"><o:p></o:p></span></span>
				</li>
		</ul>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt">
				<font size="3">
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">自</span>
						<span lang="EN-US">
								<font face="Times New Roman">2002</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">年起，基于</span>
						<span lang="EN-US">
								<font face="Times New Roman">Laszlo</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的应用程序已经被证明在百万级用户的公共</span>
						<span lang="EN-US">
								<font face="Times New Roman">Web</font>
						</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">环境中是可行的，并且是稳定可衡量的。</span>
				</font>
		</p>
<img src ="http://www.blogjava.net/wkling100/aggbug/41422.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wkling100/" target="_blank">将星泪</a> 2006-04-17 09:59 <a href="http://www.blogjava.net/wkling100/archive/2006/04/17/41422.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>工作流现状</title><link>http://www.blogjava.net/wkling100/archive/2005/10/13/15421.html</link><dc:creator>将星泪</dc:creator><author>将星泪</author><pubDate>Thu, 13 Oct 2005 06:35:00 GMT</pubDate><guid>http://www.blogjava.net/wkling100/archive/2005/10/13/15421.html</guid><wfw:comment>http://www.blogjava.net/wkling100/comments/15421.html</wfw:comment><comments>http://www.blogjava.net/wkling100/archive/2005/10/13/15421.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wkling100/comments/commentRss/15421.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wkling100/services/trackbacks/15421.html</trackback:ping><description><![CDATA[<SPAN style="WIDTH: 100%; TEXT-ALIGN: right"><B>作者<A href="http://jbpm.org/2/state.of.workflow.html#tombaeyens">Tom Baeyens </A>翻译<A href="http://www.joinwork.net/document/The%20State%20of%20Workflow2.htm#dinghong">dinghong</A></B></SPAN> <A href="http://www.joinwork.net/"><!-- =================================================================================== --></A>
<H1>前言</H1>
<P><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;如果数据库系统（ database systems）像受人尊敬的智者讲述的条理清晰的故事，那么<STRONG>工作流</STRONG>（<STRONG>workflow</STRONG>）就像一群乳臭未干的小子在大谈各自的“哲理”。之所以这样讲，我是想指出，<STRONG>工作流</STRONG>系统 （<STRONG>workflow</STRONG> management systems）还处于技术发展曲线（ <A href="http://www.ayeconference.com/wiki/scribble.cgi?read=HypeCycle">technology hype curve</A>）上的初级阶段。在这个领域我们将面临一个激动人心的阶段。 为了描述这一点，可以将<STRONG>工作流</STRONG>和关系数据库系统（RDBMS）做一个对比。当在软件开发团队中谈论RDBMS时，大部分人会有一个清晰的概念，在你和他们交流的时候，人们会通过轻微的点头表示认可或理解你所说的。可当使用工作流术语讨论<STRONG>工作流</STRONG>时，他们会摇头表示不同意，因为每个人对<STRONG>工作流</STRONG>术语都有不同的理解。</SPAN></P>
<P>
<CENTER style="MARGIN-BOTTOM: 10px"><IMG alt="the technology hype graph" src="http://www.joinwork.net/document/The%20State%20of%20Workflow.files/hype-graph.gif" border=1><BR><I>Figure 1: Workflow vs. RDBMS positioned in the hype-curve</I> </CENTER>
<P></P>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;导致形成这种状况的原因之一，是在<STRONG>工作流</STRONG>中使用了过多的概念。在这个领域中的大量规范和工具没有一个是相似的。当然，它们相互之间有重叠并且会相互参考引证。<BR>&nbsp;&nbsp;&nbsp;&nbsp;在介绍<STRONG>工作流</STRONG>时有一个话题必须包括，那就是<STRONG>工作流</STRONG>和<STRONG>业务流程管理</STRONG>（BPM）的关系。术语“<STRONG>工作流</STRONG>”通常描述人与计算机系统的一系列相关交互。在开发人员中，<STRONG>工作流</STRONG>经常被提及。有时，<STRONG>工作流</STRONG>的意思是指一些不同的UI界面。业务流程管理的范围比较广，相比之下<STRONG>工作流</STRONG>多半局限于技术领域。业务流程管理还从管理人员的角度涉及了非技术问题，比如分析、组织的效率。</P>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;在本文中，我首先解释什么是<STRONG>工作流</STRONG>管理系统，然后介绍业务流程管理的优点。接下来描述一下为什么<STRONG>工作流</STRONG>市场乍看起来如此混乱。本文给出的主要结论是：选择<STRONG>工作流</STRONG>系统是想用<STRONG>工作流</STRONG>系统的公司，将要面对的最困难的事情。为此，本文的核心部分描述了一个流程定义（process definition）的四个层次，为你选择<STRONG>工作流</STRONG>提供一个基础。本文还用中立的语言描述了<STRONG>工作流</STRONG>和BPM的通用概念。最后，给出了一些规范和工具的指导性描述。</P><SPAN class=text2><!-- =================================================================================== --></SPAN>
<H1>什么是<STRONG>工作流</STRONG>管理系统（WFMS）</H1>
<H2>定义</H2>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>工作流</STRONG>系统是以规格化的流程描述作为输入的软件组件,它维护流程的运行状态,并在人和应用之间分派活动。</P>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;为了后面的描述，我们先定义一些基本的术语：流程定义（process definition）和流程实例（process instance）. <U>一个流程定义</U>是一个业务流程或过程的规格化描述。一个<U>流程实例</U>是流程定义的一个运行实体。 都目前为止，概念还比较清晰是不是？但当再深入一步时，我们就要小心使用文字了。如何阐述流程中的步骤，现在还没有一个统一的方式。这是各种<STRONG>工作流</STRONG>规范和工具之间主要的分歧。</P>
<TABLE cellSpacing=25 cellPadding=8 border=0>
<TBODY>
<TR>
<TD style="BORDER-RIGHT: black 1px dashed; BORDER-TOP: black 1px dashed; BORDER-LEFT: black 1px dashed; BORDER-BOTTOM: black 1px dashed" vAlign=top width="100%">
<P id=activityshouldbebanned><B>为什么应当禁止使用术语“活动（activity）”...</B><BR><SPAN class=note><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN>流程定义通常用一些活动表述。我认为这是导致工作流领域所有混乱的主要原因。我告诉你为什么：因为术语“活动”混淆了状态（state）和动作（action）之间的差异。在流程中，<U>状态</U> (或者说等待状态)代表了一种对外部参与者（actor）的依赖。在流程运行时，这意味着流程引擎必须等待，直到外部参与者通知工作流管理系统指定的状态完成了。比如，等待可进一步运行的认可。<U>动作</U>是在流程运行过程中，工作流系统为响应指定事件（event）运行的一段程序逻辑（programming logic）。当流程运行过程中指定的事件发生时，工作流系统启动并执行这些动作。比如，当状态分配给一个参与者时，发一封Email。你也能看出，状态和动作是如此不同，因此使用同样的术语去描述这些概念是一个坏习惯。我的建议是避免使用术语“活动”，使用“状态”或者“动作”代替它。</SPAN></P><!-- END OF BORDER --></TD></TR></TBODY></TABLE>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>工作流系统</STRONG>另一个重要的职责是维护每一个流程运行的上下文信息。 <U>流程上下文变量（process context variable）</U> ，或简称变量，是与流程实例相关的变量。如，休假申请的开始日期、数据库中一条记录的键值、文档管理系统中一篇文档的索引等。通常在流程定义中声明这些变量，然后在流程实例生成时，这些流程变量被实例化。所有成熟的<STRONG>工作流管理系统</STRONG>都支持定制的变量类型。</P>
<H2>目标领域（Target usage）</H2>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;使用<STRONG>工作流管理系统</STRONG>的目的之一是作为企业应用系统集成（EAI）的平台。在当前大部分企业级IT架构中，各种各样的异构（heterogeneous）应用和数据库运行在企业内网中。在这些系统被应用到组织时，都有一个清晰的目标。例如，客户管理、文档管理、供应链、订单、支付、资源计划等等。让我们称这些系统为专门应用（ dedicated applications）。每一个专门应用都包含它们所支持业务流程的领域知识。这些专门应用中的自动化流程，被拼装到企业中更大的非自动化流程中。每当一个这样的专门应用安装并投入使用，都会带来涉及其他多个应用的新功能需求。企业应用系统集成（EAI）就是通过使用多个专门应用满足软件新需求的方法。有时，这只需要在两个应用之间提供数据通讯的通道。专门应用将很多业务流程硬编码在软件中。可以这么说，在你购买专门应用时，你是购买了一组固定的自动化业务流程。而<STRONG>工作流管理系统</STRONG>是不必事先知道问题域的相关信息的。<STRONG>工作流系统</STRONG>将业务流程描述作为输入并管理流程实例的执行，这使得它比专门应用更灵活（当然你也要花精力编写业务流程的规格化描述）。这就是为什么说<STRONG>工作流系统</STRONG>和专门系统是相互补充的。<STRONG>工作流系统</STRONG>可以用来管理全局的业务流程。如果专门应用支持你所需要的业务流程，那么使用专门应用。在此讨论的<STRONG>工作流系统</STRONG>的第一种使用方式就是：结合所有的专门应用，使用<STRONG>工作流系统</STRONG>构建一个EAI平台。</P>
<P class=text2><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><STRONG>工作流系统</STRONG>能够发挥很大价值的第二个使用方式是：协助涉及多人相关任务<STRONG>工作流</STRONG>软件的开发。为了达到这个目的，大部分<STRONG>工作流系统</STRONG>都有一个方便的机制，来生成执行任务的表单。对于专注于<A href="http://www.iso.ch/iso/en/iso9000-14000/iso9000/iso9000index.html">ISO</A> 或者<A href="http://www.sei.cmu.edu/cmm/cmm.html">CMM</A>认证的组织，采用这种方式使用<STRONG>工作流系统</STRONG>能够显著提高生产率。 不用将过程用文字的形式写在纸上，<STRONG>工作流系统</STRONG>使你通过流程定义建模实现过程的自动化（如使用基于Web的应用）。</P>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>工作流系统</STRONG>的第三种使用方式是：将<STRONG>工作流引擎</STRONG>嵌入到其他应用中。在前面我们谈到，专门应用将指定问题域相关的业务流程固化在软件中。开发专门应用的公司也可以将<STRONG>工作流引擎</STRONG>嵌入到他们的软件中。在这里，<STRONG>工作流引擎</STRONG>只是作为一个软件组件，对于应用的最终用户是不可见的。将<STRONG>工作流引擎</STRONG>嵌入到应用中的主要原因是为了重用（不重复发明轮子）和应用软件的可维护性。</P><!-- =================================================================================== -->
<H1>The case for workflow</H1>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;对于引入<STRONG>工作流</STRONG>的组织，能够在软件开发和业务两个层次受益。</P>
<H2>方便开发</H2>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;<STRONG>工作流管理系统</STRONG>能够简化企业级软件开发甚至维护。 </P>
<UL>
<LI><SPAN class=text2><B>降低开发风险</B> - 通过使用状态和动作这样的术语，业务分析师和开发人员使用同一种语言交谈。这样开发人员就不必将用户需求转化成软件设计了。 </SPAN>
<LI><SPAN class=text2><B>实现的集中统一</B> -业务流程经常变化，使用<STRONG>工作流</STRONG>系统的最大好处是：业务流程的实现代码，不再是散落在各种各样的系统中 。 </SPAN>
<LI class=text2><B>加快应用开发</B> - 你的软件不用再关注流程的参与者，开发起来更快，代码更容易维护。 </LI></UL>
<H2>业务流程管理 (BPM)</H2>
<P class=text2><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN>在自动化业务流程之前，分析并将它们规格化是一件艰苦但会有很好回报的工作。<A href="http://www.e-workflow.org/">e-workflow.org</A>对于分析流程能够带了的益处有不错的阐述：</P>
<UL>
<LI><SPAN class=text2><B>提高效率</B> - 许多流程在自动化过程中会去除一些不必要的步骤 </SPAN>
<LI class=text2><B>较好的流程控制</B> - 通过标准的工作方法和跟踪审计，提高了业务流程的管理 
<LI><SPAN class=text2><B>改进客户服务</B> - 因为流程的一致性，提高了对客户响应的可预见性 </SPAN>
<LI><SPAN class=text2><B>灵活</B> - 跨越流程的软件控制，使流程可以按照业务的需要重新设计。 </SPAN>
<LI class=text2><B>业务流程改进</B> - 对流程的关注，使它们趋向于流畅和简单 </LI></UL>
<P class=text2><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN>我认为他们还遗漏了一个使用<STRONG>工作流</STRONG>系统最重要的因数：提高对迭代开发的支持。如果软件中业务流程部分不容易更改，组织就会花很大的精力在开发前的业务流程分析中，希望一次成功。但可悲的是，在任何软件项目开发中，这都很少能实现。<STRONG>工作流</STRONG>系统使得新业务流程很容易部署，业务流程相关的软件可以一种迭代的方式开发，因此使用<STRONG>工作流</STRONG>系统使开发更有效、风险更低。</P>
<H2>缺失的一环（Missing link）</H2>
<H2><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;我确实认为<STRONG>工作流</STRONG>系统是企业应用开发中缺失的一环。将企业业务流程逻辑在企业级软件中实现的缺省方式是分散的。这意味着业务流程逻辑散布在各种系统中，如EJB、数据库触发器、消息代理等等。这样得到的软件难于维护，结果，企业只能将改变业务流程软件作为最后的选择。他们经常能够做的是，改变流程以适应软件。上述问题也适用于采用大型外部ERP软件包的企业。进一步，假设我们认识到这个问题，并打算将一个流程相关的代码都集中起来。对于一个流程来说这很不错，但当你要实现多个流程时，你会看到管理状态和流程变量的代码被到处复制。最后，我们会整理这些代码放到一个集中的库中。好，...这就是一个<STRONG>工作流管理系统</STRONG>了，不用费心自己来实现，你可以从本文后面的列表中选择一个</SPAN><SPAN class=text2>。</SPAN> </H2>
<H1>A closer look</H1>
<H2>WFMS interfaces</H2>
<P class=text2><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN>一个<STRONG>工作流管理系统</STRONG>以流程定义作为输入。在这里，可以将流程定义看作UML活动图、UML状态图或者有限状态机。在提交一张费用单据、申请休假、要求一个报价、...之后，<STRONG>工作流</STRONG>系统负责维护这些流程定义的执行状态和上下文。为此，需要通知<STRONG>工作流</STRONG>系统状态的变化。运行流程的状态变化可以记录下来，以备监控管理。</P>
<P>
<CENTER><IMG src="http://www.joinwork.net/document/The%20State%20of%20Workflow.files/interfaces.gif" border=1><BR><I>Figure 2: Interfaces of a WFMS</I> </CENTER>
<P></P>
<P>
<UL>
<LI><SPAN class=text2><B>定义</B>&nbsp;&nbsp;&nbsp;<STRONG>工作流</STRONG>系统的定义接口使流程开发人员能够部署流程定义。注意，这里的“流程开发人员”可以是业务分析师和软件开发人员的组合。</SPAN> <!-- START OF BORDER -->
<TABLE cellSpacing=25 cellPadding=8 border=0>
<TBODY>
<TR>
<TD style="BORDER-RIGHT: black 1px dashed; BORDER-TOP: black 1px dashed; BORDER-LEFT: black 1px dashed; BORDER-BOTTOM: black 1px dashed" vAlign=top width="100%">
<P width=100%><B>圈套（Pitfall）</B><BR><SPAN class=note>许多<STRONG>工作流管理系统</STRONG>的开发商想使你相信，通过使用他们的图形化流程开发工具，只要业务分析师就可以生成流程定义。这种幻想源于“编程很难”这样的事实。开发商的销售人员喜欢说“看，你不用写一行代码”。不用写代码是好事，可大部分开发商在这点上走的太远，忽略了在某些场合提供一种将代码集成到流程定义中的机制是很适合的。在将<STRONG>工作流</STRONG>系统作为EAI平台时，必须在流程中集成代码。开发流程定义需要业务分析师和软件开发人员的合作。一个好的图形流程设计工具应该能够支持这种合作。</SPAN></P><!-- END OF BORDER --></TD></TR></TBODY></TABLE>
<LI><SPAN class=text2><B>执行</B>&nbsp;&nbsp;&nbsp;执行接口使用户和系统可以操作流程实例。流程实例是流程定义的执行。流程定义的控制流通过状态机描述。执行接口的两个主要方法是启动一个流程实例和通知<STRONG>工作流</STRONG>系统一个状态结束了。 </SPAN>
<LI><SPAN class=text2><B>应用</B>&nbsp;&nbsp;&nbsp;应用接口代表了由<STRONG>工作流</STRONG>系统发起的<STRONG>工作流</STRONG>系统和外部系统之间的交互。当一个用户或系统操作一个流程实例的运行时，会生成一些事件（如一个迁移的执行）。流程定义中可以指定一段响应一个事件的可执行代码逻辑，这段代码和组织内外部的其他系统打交道。 </SPAN>
<LI class=text2><B>监控</B>&nbsp;&nbsp;&nbsp;管理人员通过监控接口获得流程运行的确切数据。有时，运行日志也可用于审计。 </LI></UL><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;这些是WfMC参考模型（<A href="http://www.wfmc.org/standards/model.htm">reference model of the WfMC</A>）中定义的五个接口中的四个。 </SPAN>
<H2>流程定义的四个层次</H2>
<H2><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;在下面这部分，我尝试回答这样的问题“什么是流程定义包括的内容？”。这是从各种规范和工具所使用模型的原则和概念中总结得来的，反映了大部分模型中通用的基本思想。流程定义的内容可以分为四个不同的层次：状态（state）、上下文（context）、程序逻辑（programming logic）和用户界面（UI）。</SPAN> </H2>
<H2>状态层</H2>
<P class=text2><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN>所有状态和控制流的表述，都属于业务流程的状态层。标准编程语言中的控制流来源于Von Neuman体系。控制流定义了必须被执行的指令的顺序，控制流由我们书写的命令、if语句、循环语句等确定。在业务流程中的控制流基本与此一致。但在业务流程中不是使用命令而是使用状态作为基本元素。</P>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;在流程中，<U>状态</U> (或者说等待状态)代表了一种对外部参与者（actor）的依赖。状态的意思就像“现在X系统或某某人必须作某些事，在此等待直到参与者通知这些任务已完成”。状态定义了一种对外部提供结果的依赖。状态典型的例子是批准步骤（step）。</P>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;流程定义中的状态也指定了执行依赖于哪个参与者。在活动图中，泳道（swimlanes）的标注代表这些参与者的名字。<STRONG>工作流</STRONG>系统使用这些信息构建任务列表，这是一般<STRONG>工作流</STRONG>系统都有的功能。如前所述，参与者可以是人也可以是系统。对于需要人参与的状态，<STRONG>工作流</STRONG>系统必须在运行时计算出具体的个人。这样的计算使<STRONG>工作流</STRONG>系统必须依赖于组织结构信息。关于这方面的一篇非常有趣的文章是在<A href="http://jbpm.org/2/state.of.workflow.html#furtherreading">further reading section</A>提到的“<STRONG>工作流</STRONG>应用中的组织管理”（ 'Organizational Management in Workflow Applications'）。</P>
<P><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;流程定义的控制流包含一组状态和它们之间的关系。状态之间的逻辑关系描述了哪些执行路径可以同时执行，那些不可以。同步执行路径用分叉（forks）和联合（joins）建模，异步执行路径用判断（decisions）和合并（ merges）建模。注意在大多数模型中，在每个状态之前都有一个隐式合并</SPAN>。</P>
<P><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;UML活动图经常被用来做业务流程建模。作为一种直观和通用的表达，活动图在图形表述上有一个主要问题，就是没有区分状态和动作，它们都用活动来表示。缺少这种区分（导致状态概念的缺失）是学术派对UML活动图的主要批评。UML活动图的第二个问题是在UML2.0版中引入的。当多个迁移（transitions）到达一个活动时，以前的版本规定这是一个缺省合并（merge），在2.0版中规定这是一个需要同步的缺省联合（join）。在我看来，UML活动图的图形部分仍旧可以用来对业务流程状态层次建模，只要使用时对两条构建语义作如下的变化：</SPAN> 
<OL>
<LI><SPAN class=text2>在用图形表述业务流程时，只建模状态层（状态和控制流），不要包括动作。这意味着图形中的矩形都是状态而不是活动 </SPAN>
<LI class=text2>如果多个迁移到达一个状态，缺省定义为不需要同步的合并（merges） </LI></OL>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;在流程运行过程中，<STRONG>工作流</STRONG>系统用一个令牌（token）作为指针跟踪流程的状态。这相当于Von Neuman体系中的程序计数器。当令牌到达一个状态时，它被分配给<STRONG>工作流</STRONG>系统等待的外部参与者。外部参与者可以是个人、组织或者计算机系统。我们定义流程运行的执行人或系统为“参与者”（actor）。只有在<STRONG>工作流</STRONG>系统将令牌分配给一个参与者时，才需要访问组织结构信息。<STRONG>工作流</STRONG>系统通过分配令牌构建任务列表。</P>
<H2>上下文层</H2>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;<U>流程上下文变量（process context variable）</U> ，或简称变量，是与流程实例相关的变量。流程开发人员可以使用流程变量存储跨越流程实例整个生命周期的数据。一些<STRONG>工作流管理系统</STRONG>有固定数目的数据类型，另一些你可以定义自己的数据类型。</P>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;注意变量也可以用来存放引用（ references）。一个变量可以引用如数据库中的记录、网络上的文件。什么时候使用引用，取决于使用引用数据的其他应用。</P>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;和流程变量相关的另一个令人感兴趣的方面是：<STRONG>工作流</STRONG>系统如何将数据转化为信息。<STRONG>工作流</STRONG>是用于组织内部跨越各种异构系统实现任务和数据协同的。对于业务流程中人工执行的任务，<STRONG>工作流</STRONG>系统负责从其他相关系统，如SAP、数据库、CRM系统、文档管理系统收集数据。在业务流程的每一个人工步骤，只有相关联的数据项被从异构系统中收集和计算。通过这种方式，从不同系统来的数据被转换并展现为信息。</P>
<H2 id=programminglogic>程序逻辑层</H2>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;如前所述，<U>动作</U>是在流程运行过程中，<STRONG>工作流</STRONG>系统响应指定的事件（event）执行的一段程序逻辑（programming logic）。程序逻辑可以是二进制或源代码形式的、用任何语言或脚本编写的软件。程序逻辑层是所有这些软件片断和关于在什么事件发生时调用它们的信息的组合。程序逻辑的例子包括发Email、通过消息代理发消息、从ERP系统中拿数据和更新数据库。</P>
<H2>用户界面层</H2><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;一个参与者通过向流程变量中填充数据的事件，来触发结束一个状态。比如，在请假的例子中，老板提供“同意”或“不同意”数据到流程中。某些<STRONG>工作流</STRONG>系统允许指定哪些数据可以填充到流程中，以及它们如何在流程变量中存储。通过这些信息，可以生成从用户收集信息的UI表单。基于流程定义生成用户提交表单的Web应用例子，可以访问<A href="http://jbpm.org/demo.html">the jBpm online demo</A>。</SPAN><!-- =================================================================================== --> 
<H1><STRONG>工作流</STRONG>全景</H1>
<H2>可执行流程与<STRONG>工作流管理系统</STRONG>的比较（Executional processes versus a WFMS）</H2>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;当前在BPM领域中，关于可执行业务流程的规范有趋向于统一集中的趋势。 XLANG, WSFL 和BPML合并为基于交互（消息交换）的BPEL。BPEL在面向服务体系结构(SOA)的大背景下定义。它的前提条件之一是涉及的服务必须用WSDL声明。BPEL规定了一套XML语法，这套语法可以看作一种编程语言，用来描述包括对WSDL定义的服务调用的控制流。</P>
<P><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;在可执行业务流程和基于状态的<STRONG>工作流管理系统</STRONG>所使用的方法中，我注意到了三点主要的区别：</SPAN> 
<UL>
<LI class=text2><U>基于状态与面向消息</U>：基于状态的<STRONG>工作流</STRONG>系统以状态（或者活动）概念为中心。<STRONG>工作流引擎</STRONG>维护状态并计算从一个状态到另一个状态的迁移。另一方面，像BPEL这样的可执行流程以对输入消息响应的定义为中心。一组这些响应外加其他信息（other bells and whistles）可以看作一个业务流程。这也解释了为什么BPEL可以看作是对基于状态的<STRONG>工作流</STRONG>系统的某些方面的补充。一个响应输入消息的BPEL onMessage事件处理器，可以在<STRONG>工作流</STRONG>状态之间的迁移中执行。 
<LI><SPAN class=text2><U>流程实例ID与消息相关处理</U>：可执行业务流程的复杂性之一来自消息相关性的处理。流程描述的一部分必须说明BPEL引擎如何从输入消息中确定具体流程的标识。这必须基于输入消息的一个数据项。而<STRONG>工作流</STRONG>系统在每个流程实例生成同时生成了实例ID，客户端在后续调用引擎API时使用这个ID。 </SPAN>
<LI class=text2><U><STRONG>工作流引擎</STRONG>API与抽象服务端点（endpoint）</U>：<STRONG>工作流</STRONG>系统提供一组集中的API，客户端通过调用API完成与所有流程实例的交互。在可执行业务流程中，每个流程表现为一个服务。这意味着对于每个流程定义都有一个不同的访问点。 </LI></UL>
<H2>学术界</H2><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;学术界对<STRONG>工作流</STRONG>的研究可以回溯到上个世纪七十年代。在当前，研究领域趋向于认为<A href="http://www.daimi.au.dk/PetriNets/">petr 网</A>是<A href="http://tmitwww.tm.tue.nl/research/patterns/main_conclusions.htm">所有流程定义语言之母</A>。关于petri网已有大量先进的分析技术，去年在 <A href="http://tmitwww.tm.tue.nl/bpm2003/">2003 conference on Business Process Management</A>上我有幸会晤了Petri教授。对于大部分人能够访问和理解的有关Petyri网最好的研究之一是<STRONG>工作流</STRONG>模式<A href="http://tmitwww.tm.tue.nl/research/patterns">(workflow patterns)</A>。<STRONG>工作流</STRONG>模式比较了大量的<STRONG>工作流管理系统</STRONG>并以petri网的术语表述了通用流程建模概念。</SPAN> 
<H2 id=opensourceprojects>开放源代码项目</H2>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;最后我们看看真实世界中的<STRONG>工作流管理系统</STRONG>。选择一个<STRONG>工作流管理系统</STRONG>是一件困难的事情，但有选择总比没有选择好。:-) 本文阐述<STRONG>工作流</STRONG>基本概念的目的之一，就是使你能够作更好的选择。但我也意识到，对于现在的软件架构师来说，选择<STRONG>工作流</STRONG>系统是一件最具挑战性的工作。</P>
<P><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;下面的列表来源于三个地方：<A href="http://jbpm.org/article.html">my previous article</A>, <A href="http://www.manageability.org/blog/stuff/workflow_in_java/view">the list of Carlos E Perez</A>, 和 <A href="http://www.topicus.nl/topwfm/Tooloverzicht.htm">list by Topicus</A>. </SPAN></P>
<UL>
<LI><SPAN class=text2><B><A href="http://www.jbpm.org/">jBpm</A></B> - jBpm是本文作者编写的一个灵活可扩展的<STRONG>工作流管理系统</STRONG>。作为jBpm运行时server输入的业务流程使用简单强大的语言表达并打包在流程档案中。jBmp将<STRONG>工作流</STRONG>应用开发的便利性和杰出的企业应用集成（EAI）能力结合了起来。jBmp包括一个Web应用程序和一个日程安排程序。jBmp是一组J2SE组件，可以作为J2EE应用集群部署。 </SPAN>
<LI><SPAN class=text2><B><A href="http://openebxml.sourceforge.net/">OpenEbXML</A></B> - OpenebXML项目致力于提供一个ebXML框架，主要支持不久将由 UN/CEFACT和OASIS发布的ebXML规范2.0版。 </SPAN>
<LI><SPAN class=text2><B><A href="http://werkflow.codehaus.org/">Werkflow</A></B> - Werkflow是一个灵活可扩展的基于流程和状态的<STRONG>工作流引擎</STRONG>。它的目标是满足可以想象的所有工作流程，从企业级的业务流程到小范围的用户交互流程。通过使用可插拔和分层结构，可以方便地容纳各种<STRONG>工作流</STRONG>语义。 </SPAN>
<LI><SPAN class=text2><B><A href="http://www.opensymphony.com/osworkflow">OSWorkflow</A></B> - OSWorkflow最独到之处是绝对的灵活。 </SPAN>
<LI><SPAN class=text2><B><A href="http://wfmopen.sourceforge.net/">wfmOpen</A></B> - WfMOpen是WfMC和OMG中所谓<STRONG>工作流</STRONG>设施（workflow facility） (<STRONG>工作流引擎</STRONG>)的J2EE实现。<STRONG>工作流</STRONG>通过扩展的XPDL描述。 </SPAN>
<LI><SPAN class=text2><B><A href="http://www.ofbiz.org/docs/workflow.html">OFBiz</A></B> - OFBiz<STRONG>工作流引擎</STRONG>基于WfMC和OMG的规范，使用XPDL作为流程定义语言。 </SPAN>
<LI><SPAN class=text2><B><A href="http://bonita.forge.objectweb.org/">ObjectWeb Bonita</A></B> - Bonita是一个符合WfMC规范、灵活的协同<STRONG>工作流</STRONG>系统。 对于各种动作如流程概念建模、定义、实例化、流程控制和用户交互等提供了全面的集成图形工具。 100% 基于浏览器、使用SOAP和XML数据绑定技术的Web Services封装了已有的<STRONG>工作流</STRONG>业务方法并将它们以基于J2EE的Web Service形式发布。基于活动预测模型的第三代<STRONG>工作流引擎</STRONG>。 </SPAN>
<LI><SPAN class=text2><B><A href="http://www.bigbross.com/bossa/">Bigbross Bossa</A></B> -速度非常快、轻量级的引擎，使用富有表达能力的Petri网定义<STRONG>工作流</STRONG>，不要求关系数据库，使用简单，能和Java应用集成。事实上，它是按嵌入式设计的。 </SPAN>
<LI><SPAN class=text2><B><A href="http://xflow.sourceforge.net/">XFlow</A></B> - XFlow运行于EJB和servlet容器中。 </SPAN>
<LI><SPAN class=text2><B><A href="http://taverna.sourceforge.net/">Taverna</A></B> - Taverna项目的目标是提供一种语言和软件工具，方便在eScience中使用<STRONG>工作流</STRONG>和分布计算技术。 </SPAN>
<LI><SPAN class=text2><B><A href="http://shark.enhydra.org/">Enhydra Shark</A></B> - Shark完全基于WfMC和OMG标准，使用 XPDL作为<STRONG>工作流</STRONG>定义语言。流程和活动的存储使用Enhydra DODS。 </SPAN>
<LI><SPAN class=text2><B><A href="http://www.powerfolder.org/">PowerFolder</A></B> - PowerFolder包括开发人员使用的studio，管理环境和一个运行时引擎。 </SPAN>
<LI><SPAN class=text2><B><A href="http://www.dstc.edu.au/Research/Projects/Pegamento/Breeze/breeze.html">Breeze</A></B> - Breeze一个轻量级、跨平台、基于组件的<STRONG>工作流引擎</STRONG>原型。 </SPAN>
<LI><SPAN class=text2><B><A href="http://www.openbusinessengine.org/index.html">Open Business Engine</A></B> - Open Business Engine是一个开放源码的Java<STRONG>工作流引擎</STRONG>，支持WfMC规范，包括接口1（XPDL）、接口2/3（WAPI）和接口5。OBE为活动的运行提供了一个可控的集中环境。OBE主要基于J2EE实现。 </SPAN>
<LI><SPAN class=text2><B><A href="http://openwfe.sourceforge.net/">OpenWFE</A></B> - OpenWFE是一个开放源码的Java<STRONG>工作流引擎</STRONG>。 它包括可升级的三个组件：引擎、工作列表和Web界面。它的流程定义语言虽然使用XML格式，其灵感来源于 Scheme，一种Lisp方言。 </SPAN>
<LI><SPAN class=text2><B><A href="http://freefluo.sourceforge.net/">Freefluo</A></B> - Freefluo是一个使用Web Service的<STRONG>工作流</STRONG>协同工具，可以处理WSDL的Web Service调用。支持两种XML格式的<STRONG>工作流</STRONG>语言：IBM的WSFL和XScufl。Freefluo非常灵活，它的核心是不与任何<STRONG>工作流</STRONG>语言或执行架构关联的可重用协同框架。 Freefluo包括可执行使用WSFL一个子集描述的<STRONG>工作流</STRONG>的运行库。 </SPAN>
<LI><SPAN class=text2><B><A href="http://www.tripodsoft.com/products/intro.htm">ZBuilder</A></B> - ZBuilder3是第二代<STRONG>工作流</STRONG>开发管理系统，也是一个开放源码产品。它为不同的<STRONG>工作流引擎</STRONG>和<STRONG>工作流</STRONG>定义了一组标准的JMX管理接口。 </SPAN>
<LI><SPAN class=text2><B><A href="http://www.smartcomps.org/twister/">Twister</A></B> - Twister的目标是提供新一代、易集成、应用Java领域中最新成果、面向B2B的<STRONG>工作流</STRONG>解决方案。流程引擎基于BPEL业务流程规范和Web Service标准。 </SPAN>
<LI class=text2><B><A href="http://con-cern.org/">Con:cern</A></B> - con:cern<STRONG>工作流引擎</STRONG>基于扩展的案例（case）处理方法，流程由一组具有前后条件的活动组成。 </LI></UL>
<H2 id=commercialvendors>商业软件提供商</H2>
<UL>
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://e-docs.bea.com/wlintegration/v2_1/interm/bpmhome.htm">Bea's WLI</A> </SPAN>
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://www.carnot-usa.com/">Carnot</A> </SPAN>
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://www.dralasoft.com/products/workflow/">Dralasoft</A> </SPAN>
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://www.filenet.com/">Filenet</A> </SPAN>
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://www.fsw.fujitsu.com/products/InterstageSuite/BPM/overview.html">Fujitsu's i-Flow</A> </SPAN>
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://www-106.ibm.com/developerworks/ibm/library/i-holo/">IBM's holosofx tool</A> </SPAN>
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://www.intalio.com/products/index.html">Intalio</A> </SPAN>
<LI class=text2><A class=style4 href="http://www.joinwork.net/" target=_blank><STRONG>Joinwork</STRONG></A> （译者加:-) ） 
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://www.lombardisoftware.com/">Lombardi</A> </SPAN>
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://oakgrovesystems.com/">Oakgrove's reactor</A> </SPAN>
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://www.oracle.com/ip/deploy/ias/integration/">Oracle's integration platform</A> </SPAN>
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://www.qlinktech.com/">Q-Link</A> </SPAN>
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://www.sap.com/solutions/netweaver/">SAP's NetWeaver</A> </SPAN>
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://www.savvion.com/products/">Savvion</A> </SPAN>
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://www.seebeyond.com/products/ICAN_productsEinsight.asp">Seebeyond</A> </SPAN>
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://www.sonicsoftware.com/products/sonic_orchestration_server/">Sonic's orchestration server</A> </SPAN>
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://www.staffware.com/products/">Staffware</A> </SPAN>
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://www.ultimus.com/">Ultimus</A> </SPAN>
<LI style="PADDING-BOTTOM: 0px"><SPAN class=text2><A href="http://www.versata.com/products/inSuite/products.html">Versata</A> </SPAN>
<LI class=text2 style="PADDING-BOTTOM: 0px"><A href="http://www.webmethods.com/content/1,1107,Model,FF.html">WebMethod's process modeling</A> </LI></UL>
<H2>工具目录</H2>
<UL>
<LI><SPAN class=text2><A href="http://dmoz.org/Computers/Software/Workflow/Products/">http://dmoz.org/Computers/Software/Workflow/Products/</A> </SPAN>
<LI class=text2><A href="http://is.twi.tudelft.nl/~hommes/tools.html">A collection of links to tools for modelling business processes and workflows maintained by Bart-Jan Hommes at TU Delft, the Netherlands.</A> </LI></UL>
<H2>规范</H2>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;Michael zur Muehlen作了一个所有<STRONG>工作流</STRONG>相关规范的介绍性的<A href="http://www.wfmc.org/standards/docs/Process_Management_Standards_files/frame.htm" target=_blank>幻灯片</A>，很不错。</P>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;我同意<A href="http://www.staffware.com/understanding-bpm/useful-reading/The-Problem-with-Process-Management-Standards.asp?ComponentID=8058&amp;SourcePageID=7348#1">John Pyke</A> 和 <A href="http://tmitwww.tm.tue.nl/research/patterns/download/ieeewebflow.pdf">Wil van der Aalst</A> 的观点：<STRONG>工作流</STRONG>标准还处于制定阶段。现在存在大量相互丛叠的规范。</P>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;在我看来，导致规范如此之多而同时每个规范的应用又很有限的原因是，在<STRONG>工作流</STRONG>最基础概念上大家达成的共识很少。<STRONG>工作流</STRONG>是最容易让你感到心烦的话题，因为<STRONG>工作流</STRONG>本身的概念会和其他相关概念和技术混淆在一起。可以举一个具体的例子，比如说<STRONG>工作流</STRONG>完全是对Web Service的补充。你可以通过暴露接口以Web Service的方式访问一个<STRONG>工作流</STRONG>管理系统，但是不能假定总是必须通过Web Service接口访问<STRONG>工作流</STRONG>系统接口。一些规范造成了这样的假设。除了Web Service，其他容易混淆的概念和技术包括：Email、流程之间的通讯、Web应用和组织结构。</P>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;在<STRONG>工作流</STRONG>领域第一个致力于标准化工作的是<A href="http://wfmc.org/">Workflow Management Coalition</A> (WfMC)，开始于 1993。 WfMC发布的<A href="http://wfmc.org/standards/model.htm">参考模型</A>很不错，它定义了<STRONG>工作流管理系统</STRONG>和其他相关部分之间的接口。WfMC的另一项成果是<A href="http://www.wfmc.org/standards/docs/TC-1025_10_xpdl_102502.pdf">XPDL</A>规范。 XPDL定义了描述<STRONG>工作流</STRONG>声明部分（declarative part）的XML结构。我个人认为，参考模型和XPDL是目前最好的规范。</P>
<UL>
<LI><SPAN class=text2><A href="http://www.jcp.org/en/jsr/detail?id=207"><B>JSR 207: Java的流程定义</B></A> -是由<A href="http://www.jcp.org/">Java Community Process (JCP)</A> 发起，如何在J2EE应用服务器中实现业务流程自动化的标准。其基本模型是定义一个特殊类型的ejb session bean，作为一个业务流程的接口。JSR207标准化一组XML元标记（meta tags）作为JSR175元数据的一部分。JSR207 将session bean和元数据作为ejb容器的输入，然后生成绑定方法的代码，这些方法在元数据中描述。此规范还处于初级阶段，没有发布任何内容。专家小组成立于 March 2003. </SPAN>
<LI><SPAN class=text2><B><A href="http://www.wfmc.org/">WfMC's</A> <A href="http://www.wfmc.org/standards/docs/TC-1025_10_xpdl_102502.pdf">XPDL</A></B> - WfMC是由约300家成员参加的组织，基于参考模型定义了一系列的标准。参考模型用用例（use case）的形式描述了<STRONG>工作流</STRONG>系统和其他相关部分之间的关系。XPDL是WfMC制定的描述业务流程控制流（control flow ）的XML格式规范。 </SPAN>
<LI><SPAN class=text2><B><A href="http://www.ebxml.org/">ebXML's</A> <A href="http://ebxml.org/specs/ebBPSS.pdf">BPSS</A></B> - ebXML是协同流程的相关标准集，主要关注不同公司流程之间的通讯。可以看作EDI的继承者。 ebXML是由OASIS和UN/CEFACT联合发起。 BPSS 是ebXML的规范，其中的概念和本文阐述的很接近。 </SPAN>
<LI><SPAN class=text2><B><A href="http://www.bpmi.org/">BPMI's</A> BPML &amp; WSCI</B> - (Intalio, Sun, SAP, ...)BPMI 也定义了一个规范 (BPMN) ，描述如何将“可执行”业务流程可视化的表现。 </SPAN>
<LI><SPAN class=text2><B><A href="http://www-106.ibm.com/developerworks/library/ws-bpel/">BPEL</A></B> - (Microsoft, BEA, IBM, SAP &amp; Siebel) BPEL由一系列基于消息交换的规范（ XLANG, WSFL, BPML）产生。还有一个将此规范引入到Java的提案: <A href="http://www-106.ibm.com/developerworks/webservices/library/ws-bpelj/">BPELJ</A>。 此规范描述如何处理输入的消息，而不是对流程状态进行建模。就像本文提到的，它不是一个关于业务流程规格化定义的规范。简单的说，可以将它看作XML形式的编程语言，提供将WSDL-Services组合成控制流的能力。顾名思义，此规范重点在（也不只限于）Web Service。</SPAN> 
<LI class=text2><B><A href="http://www.omg.org/docs/formal/00-05-02.pdf">OMG's Workflow management facility</A></B> - 基于WfMC规范，定义如何向CORBA转换。 
<LI><SPAN class=text2><B><A href="http://www.uml.org/">UML</A></B> - UML定义了建模和设计软件系统的9类图。每类图包括可视化的表示和语义。其中活动图的目的就是要可视化的表现业务流程。 注意到在一个流程定义包含四个层次的内容，我想指出的是：一个流程定义包含的内容远远多于它的可视化部分。UML只涉及了可视化部分。 </SPAN>
<LI><SPAN class=text2><B><A href="http://www.rosettanet.org/">RosettaNet</A></B> - RosettaNet主要定义了一组 Partner Interface Processes (PIP). 一个 PIP 描述了一个有两个交易参与者、包括消息格式的流程。 </SPAN>
<LI class=text2><B><A href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=ubl">UBL</A></B> - The Universal Business Language (UBL)定义了用于不同组织间通讯的XML文档标准库。可以看作是对ebXML的补充，因为ebXML只定义了建立组织间流程的基础。此规范的竞争对手是 RosettaNet标准中的一个子集。 </LI></UL><!-- =================================================================================== -->
<H1>结论</H1>
<P><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;我在本文中指出<STRONG>工作流</STRONG>市场还属于年轻而又混乱（young and wild）的阶段，但已经有可靠的工具存在了: </SPAN>
<OL>
<LI><SPAN class=text2>到目前，像J2EE和.NET这样成熟的集成平台才可用。在这样一个平台上运行</SPAN><SPAN class=style5><STRONG><FONT face=Simsun size=2>工作流</FONT></STRONG></SPAN><SPAN class=text2><STRONG>管理系统</STRONG>才能真正发挥<STRONG>工作流</STRONG>系统的附加价值。这也是为什么只有在今天，<STRONG>工作流</STRONG>系统才被重新发现。 </SPAN>
<LI class=text2>在 'The case for workflow'一节，我们介绍了引入<STRONG>工作流管理系统</STRONG>，是如何同时在技术和业务上带来投资回报的。 
<LI><SPAN class=text2><STRONG>工作流</STRONG>在技术发展曲线的位置表明，BPM和<STRONG>工作流</STRONG>中使用的概念还需要明确。 </SPAN>
<LI class=text2>“开放源代码项目”和“商业软件提供商”列表中的工具，可以让你获得<STRONG>工作流</STRONG>和<STRONG>业务流程管理</STRONG>的益处。 </LI></OL>
<P><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;从以上所有这些中能得到的结论是：</SPAN> 
<OL>
<LI><SPAN class=text2>规范还没有成熟，没有标准被大范围采用 </SPAN>
<LI><SPAN class=text2>对于现在想应用BPM的公司来讲，比较<STRONG>工作流</STRONG>系统是一个极其困难的挑战 </SPAN>
<LI class=text2>尽管标准化工作慢了一拍，可好的<STRONG>工作流管理系统</STRONG>还是有的。这对于已经在挑选<STRONG>工作流</STRONG>系统的组织来说是一个好消息。 </LI></OL>
<P class=text2>&nbsp;&nbsp;&nbsp;&nbsp;我希望本文能够激发你对<STRONG>工作流</STRONG>的兴趣并且能够为你进行有效的对比提供正确的背景知识。</P><!-- =================================================================================== -->
<H1 id=furtherreading>Further reading</H1>
<UL>
<LI><SPAN class=text2><B><A href="http://tmitwww.tm.tue.nl/research/patterns/">Workflow Patterns</A></B> -Wil van der Aalst教授的<STRONG>工作流</STRONG>模式学术研究网站 </SPAN>
<LI><SPAN class=text2><B><A href="http://www.ebpml.org/">ebpml.org</A></B> - 有关业务流程管理和<STRONG>工作流</STRONG>的网站，信息量大、全面 </SPAN>
<LI><SPAN class=text2><B><A href="http://www.bpmg.org/">Business process management group</A></B> - The Business Process Management Group (founded in 1992) is a global business club exchanging ideas and best practice in business process and change management. </SPAN>
<LI><SPAN class=text2><B><A href="http://www.enix.co.uk/">Enix</A></B> - 英国流程管理顾问公司，在网站上有不错的内容 </SPAN>
<LI><SPAN class=text2><B><A href="http://www.ebizq.net/">ebizq.net</A></B> - Commercial community that has booths, webinars and other interesting stuff put together in a nice website. </SPAN>
<LI><SPAN class=text2><B><A href="http://viking.gmu.edu/http/syst511/vg511/AppC.html">An introduction to petri nets</A></B> - The title says it all. </SPAN>
<LI><SPAN class=text2><B><A href="http://www.workflow-research.de/Publications/PDF/MIZU-ITM(2004).pdf">Organizational Management in Workflow Applications</A>- An interesting article that discusses the relation between business processes and the organisational data involved. </SPAN>
<LI><SPAN class=text2><B><A href="http://devresource.hp.com/drc/technical_white_papers/WSOrch/WSOrchestration.pdf">Web services orchestration</A></B> - an HP-paper that reviews the emerging technologies tools and standards. (Januari 2003) </SPAN>
<LI class=text2><B><A href="http://www.webservicesarchitect.com/content/articles/oriordan01.asp">Business process standards for web services</A></B> - An article that discusses the various aspects involved in workflow and BPM. </LI></UL>
<H1>Thanks</H1><SPAN class=text2>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN>A special thanks for Gustavo Maciel Dias Vieira and Jef Vanbockryck for their valuable feedback on the draft versions of this article. <!-- START OF BORDER -->
<TABLE cellSpacing=25 cellPadding=8 width="100%" border=0>
<TBODY>
<TR>
<TD style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" vAlign=top width="100%">
<P id=tombaeyens width=100%><B>about the author<BR><BR>Tom Baeyens</B> leads the jBpm support organisation, specialized in Java, workflow and business process management. His expertises are both at a technical, analysis and at a business level. Tom is the founder of <A href="http://jbpm.org/">jbpm.org</A>, an open source workflow engine. Tom is also a member of the expertgroup of the JSR 207: <A href="http://www.jcp.org/en/jsr/detail?id=207">Process Definition for Java</A>. Tom Baeyens can be contacted at <B><FONT family="courier new">tom at jbpm.org</FONT></B> </P><!-- END OF BORDER --></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=25 cellPadding=8 width="100%" border=0>
<TBODY>
<TR>
<TD style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" vAlign=top width="100%">
<P id=tombaeyens width=100%><B><A name=dinghong></A>译者<BR><BR>dinghong</B>嵌入式Java工作流系统<A href="http://www.joinwork.net/" target=_blank>Joinwork</A>的设计开发者之一。email：<A href="mailto:dinghong@joinwork.net">dinghong@joinwork.net</A>。 </P><!-- END OF BORDER --></TD></TR>
<TR>
<TD style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" vAlign=top>
<P class=text2>以下为译者加：</P>
<P class=text2>1、网友flyisland对本文的<A href="http://www.blogbus.com/blogbus/blog/diary.php?diaryid=401239" target=_blank>可视化展现</A>，很直观！</P></TD></TR></TBODY></TABLE></B><img src ="http://www.blogjava.net/wkling100/aggbug/15421.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wkling100/" target="_blank">将星泪</a> 2005-10-13 14:35 <a href="http://www.blogjava.net/wkling100/archive/2005/10/13/15421.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>表现层框架  Struts/Tapestry/JSF    架构比较</title><link>http://www.blogjava.net/wkling100/archive/2005/10/10/15140.html</link><dc:creator>将星泪</dc:creator><author>将星泪</author><pubDate>Mon, 10 Oct 2005 07:48:00 GMT</pubDate><guid>http://www.blogjava.net/wkling100/archive/2005/10/10/15140.html</guid><wfw:comment>http://www.blogjava.net/wkling100/comments/15140.html</wfw:comment><comments>http://www.blogjava.net/wkling100/archive/2005/10/10/15140.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wkling100/comments/commentRss/15140.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wkling100/services/trackbacks/15140.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Struts/Tapestry/JSF是目前J2EE表现层新老组合的框架技术。从诞生时间上看，Struts应该比较早，使用得非常广泛，Tapestry 3.0逐渐引起广泛的重视，正当Tapestry即将大显身手时期，SUN推出JSF标准技术，虽然JSF一开始推出尚不成熟，留出了一段空白期，但是随着JSF1.1标准推出，JSF开始正面出击，粉面隆重登场了。 
<P align=left>　　其实，JSF和Tapestry也并不是那种头碰头的相同竞争性技术，两者还是各有侧重点的，不过比较细微，但是这种细微点在实现一个大工程时可能带来不同的感受和变化。</P>
<P align=left>　　首先，我们从一个高度来抽象一下表现层框架应有的技术架构，下图可以说所有表现层框架技术都必须实现的功能架构图：</P>
<P align=center><IMG height=236 alt="" src="http://www.kissjava.com/onestep/images/h000/h26/img200509172341280.jpg" width=219></P>
<P align=left>　　当然，我们不必废话罗嗦MVC模式，MVC模式是基准模式，现在框架技术已经不必再拼是否是MVC模式了。 在上图MVC模式基础上，一个表现层框架无外乎要实现图中的三个功能：</P>
<P align=left>1.在当前页面能够显示一个组件对象的内容；而不是象纯JSP那样，需要在Jsp页面写入“调用对象方法”的Java代码。</P>
<P align=left>2.当用户按下页面的提交按扭或链接后，事件发生，这时应该触发服务器端并将当前页面的参数提交给服务器。这种机制表现在Form表单提交和有参数的链接&lt;a href=""&gt;&lt;/a&gt;</P>
<P align=left>3.从一个页面视图直接跳转到另外一个页面视图，单纯的导航作用。</P>
<P align=left>我们通过下表来比较这 三种框架在实现上图各个功能时技术细节，从而得出他们的异同点和偏重点。</P>
<TABLE cellSpacing=1 cellPadding=1 width="100%" border=0>
<TBODY>
<TR>
<TD bgColor=#cccccc>
<TABLE width="100%" border=0>
<TBODY>
<TR>
<TD width="16%">&nbsp;</TD>
<TD width="29%">Struts</TD>
<TD width="33%">Tapestry3.0</TD>
<TD width="22%">JSF</TD></TR>
<TR bgColor=#ffffff>
<TD bgColor=#999999>在View显示的组件要求</TD>
<TD>
<P>组件必须继承ActionForm</P></TD>
<TD>分显式调用和隐式调用<BR>组件必须继承BaseComponent</TD>
<TD>普通POJO<BR>无需继承<BR>Managed Bean</TD></TR>
<TR bgColor=#ffffff>
<TD bgColor=#999999>组件在View显示粒度</TD>
<TD>View页面只能显示与表单对应的ActionForm，配置中Action ActionForm 页面一般只能1:1:1关系。</TD>
<TD>可将组件嵌入页面任何一行，对使用组件数量无限制。</TD>
<TD>同Tapestry</TD></TR>
<TR bgColor=#ffffff>
<TD bgColor=#999999>页面分区tiles</TD>
<TD>使用Tiles标签库实现，需要另外tiles-def.xml配置文件</TD>
<TD>组件有自己的视图页面，通过调用组件即直接实现多个页面组合。强大自然的页面组合是其特点。</TD>
<TD>通过组件+标签库实现Subview,但如需重用Layout,还要结合Tiles.</TD></TR>
<TR bgColor=#ffffff>
<TD bgColor=#999999>页面跳转</TD>
<TD>使用标签库html:link中写明目标URL，URL名称需要对照配置文件的path命名,与组件Action耦合。</TD>
<TD>URL名称是目标的组件名称，不涉及URL和路径等操作，方便稳固。</TD>
<TD>类似Struts，也需要在配置文件中查找,与组件分离。</TD></TR>
<TR bgColor=#ffffff>
<TD bgColor=#999999>参数传递</TD>
<TD>使用html:link时传递参数超过一个以上处理麻烦。</TD>
<TD>直接调用组件，直接赋予参数，没有参数个数限制</TD>
<TD>参数分离传递给组件</TD></TR>
<TR bgColor=#ffffff>
<TD bgColor=#999999>事件触发</TD>
<TD>通过表单提交submit激活，不能细化到表单里字段。</TD>
<TD>能够给于表单每个字段贴一个事件，事件组件必须实现PageListener接口</TD>
<TD><SPAN id=intelliTxt><CODE><FONT face=新宋体>同Tapestry，事件组件必须实习ActionListener 接口</FONT></CODE></SPAN></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<P><STRONG>Struts组件编程模型</STRONG></P>
<P>　　Struts实现组件编程时有一些复杂：经常为一个页面中需要引入多个组件而头疼，因为Struts中无法直接引入多个组件，必须绕一些圈子:</P>
<P>　　一般分两种情况：如果同一个Action就可以对付这些组件，那么在这种情况下有两个办法：</P>
<P>1.将这多个组件装入一个ActionForm中，如使用<SPAN class=unnamed3>MapForm</SPAN>等机制；</P>
<P>2.手工将多个组件装入request/session等scope中，然后根据其名称在jsp中获得。</P>
<P>　　这两个方法都有缺点： 第一种办法经常一个ActionForm弄得面目全非，变成一个大杂烩，违反了OO分派封装的原则；第2种办法其实又回到jsp编程；</P>
<P>　　第二种情况，如果这些组件必须有预先由不同的Action来处理，每个组件必须经过Action --&gt;ActionForm流程，在这种情况下有两种办法：</P>
<P>1.使用Tiles, 不同流程输出到同一个页面的不同区域。是一种并行处理方式。</P>
<P>2. 对多个流程首尾相连，第一Action forward结果是第二个Action，最后输出一个Jsp，在这个jsp中就可以使用前面多个流程的多个ActionForm了，这属于串行方式。</P>
<P><STRONG>Struts组件模型缺点</STRONG></P>
<P>　　Struts组件编程必须限定在Action/ActionForm/JSP这三个框框中做文章，难度相对比较大，而Tapestry/JSF则没有太多这些技术框框限制，两者在组件编程方面更让编程者自由一些，方便一些，这也是组件型框架的优势吧。</P>
<P><STRONG>Struts标签库</STRONG></P>
<P>　　在Struts中，经常需要使用标签库来显示组件ActionForm中内容，这就涉及到一个结合的问题，标签库是别人写的，参考Struts的标签库用法，而组件是自己的，难度和麻烦就体现在这个结合点上。</P>
<P>　　JSF基本思路和Struts差不多，只不过换了不同标签库，也需要标签库+组件的结合思考，不过因为组件这里是通用组件，没有什么限制，所以这样比Struts要轻松一些。</P>
<P>　　Tapestry使用了组件库概念替代了标签库，没有标签库概念，这样就没有标签库和自己的组件需要结合的问题，都是组件的使用，组件中分Tapestry标准组件和自己定义的组件，这也是接触了Jsp体系的人学习Tapestry面临的一个思路转换。</P>
<P>　　具体以页面跳转为例子，页面跳转是靠链接&lt;a href="目标"&gt;&lt;/a&gt; 实现，链接是页面经常使用的元素。</P>
<P>　　Struts提供的html:link在频繁使用就特别不方便，尤其在传递多个参数时：其中html:link的page值，是跳转对方页面或Action的path，这个path一般需要到struts-config.xml查找Action的相应path,一旦配置文件path值修改，涉及到这个所有相关页面都要修改。</P>
<P>　　JSF将链接概念划分两个方面：导航性质和事件激活，在导航方面还是需要到配置faces-config查询Navigation的from-outcome的值。</P>
<P>　　由于Tapestry没有标签库概念，只有组件或页面两个概念，因此，链接跳转目标要么是组件，要么是页面，简洁简单，它没有多余的path概念，就是组件名，也就是对象名称，组件名称和path名称合二为一。</P>
<P><STRONG>总结</STRONG></P>
<P>　　JSF在很大程度上类似Struts，而不是类似Tapestry，可以说是一种Struts 2.0，都是采取标签库+组件的形式，只是JSF的组件概念没有象Struts那样必须继承ActionForm的限制；JSF在事件粒度上要细腻，不象Struts那样，一个表单一个事件，JSF可以细化到表单中的每个字段上。</P>
<P>　　JSF只有在组件和事件机制这个概念上类似Tapestry，但是不似Tapestry那样是一个完全组件的框架，所以，如果你做一个对页面要求灵活度相当高的系统，选用Tapestry是第一考虑。</P>
<P>　　Struts/JSF则适合在一般的数据页面录入的系统中，对于Struts和JSF的选用，我目前个人观点是：如果你是一个新的系统，可以直接从JSF开始；如果你已经使用Struts，不必转换，如果需要切换，可以将JSF和Tapestry一起考虑。</P>
<P>　　另外，JSF/Tapestry不只是支持Html，也支持多种客户端语言如WML或XUI等。</P>
<P>　　这三者之间关系：如果说Struts是左派；那Tapestry则是右派；而JSF则是中间派，中庸主义是SUN联盟的一贯策略。</P>
<P>　　当然，你也可以发表你在实践中这三者任何一个的使用感受，以使得后来者有一个比较。</P>
<P><A href="http://www.jdon.com/idea/jsf-struts.htm" target=_blank></A>&nbsp;</P><img src ="http://www.blogjava.net/wkling100/aggbug/15140.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wkling100/" target="_blank">将星泪</a> 2005-10-10 15:48 <a href="http://www.blogjava.net/wkling100/archive/2005/10/10/15140.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>