# 前言
Spring Web Flow = SWF
最近学习了《Spring实战》的第八章,Spring Web Flow。感觉是个不错的东西。无奈发现网上的资料少之又少。后来发现根本没有人用这个技术。
一般没人用某项技术的原因就是要么这个技术不成熟,要么这个技术并不好。所以我特地去找了找 SWF 技术的优缺点,顺便分享一下。
时间紧迫,只是翻译每段核心内容。
# 原文作者的建议
I'm going to play devil's advocate and say don't use it for anything other than simple use cases. Simple use cases meaning no ajax calls, no modal dialogs, no partial updates just standard html forms/flows for simple persistence (i.e page A -> page B -> Page C where each 'page' maps to a view-state definition in a 1 to 1 relationship all defined in the same flow xml file).
除了简单 1 对 1 关系,任何场合都不要用。
# 缺点
Yes everything is in xml files in theory it is suppose to be simple but when you have multiple flow xml files each with multiple state definitions and possibly subflow definitions it can become cumbersome to maintain or easily determine what the sequential logic of a flow is. (kind of like the old "GOTO operator" where any part of a flow logic can jump back to any previously or later defined part making the flow logic although seemingly "sequential" in xml... un-intuitive to follow)
理论上,XML 文件很简单,但是很多 XML 文件的话就容易混乱。有点像老式语法 GOTO 的感觉。
Some features of Spring Webflow's documentation are unintuitive or flat out undocumented leading to hours of trial and error. For instance, exception handeling, usauge of 'output' tag (only works in subflow->back to parent caller undocumented), sending back flash view responses to a user is also unintuitive and uses a different container than Spring MVC (many times when a flow ends you want to send a msg to the user that is defined in a controller outside of webflow... but since the flow ended you can't do it with in spring webflow using flashScope container), etc...
有些 SWF 的特性是反直觉的,调试起来也很困难。
Adding subflows although sounds good does not reduce complexity actually increases it. Due to the way subflows are defined. Definitions are long and complex and can be confusing when you have many end-states in both the main parent flow and the child subflows.
增加子流程似乎听起来很好但实际上并没有减少流程的复杂性,反倒是提升了流程的复杂性。
Initial setup and configuration can be painful if integrating with certain 3rd party view frameworks like Apache Tiles or Theymeleaf... I recall spending a few hours if not days on this.
State snapshots (Saving the user's input between pages) although a powerful feature from Flow A's view-state_1 <-> Flow A's view-state_2 and vise versa. This does not work between Main Flow A <-> Sub Flow B and vise versa... forcing the developer to manually bind (or rather hack) saving a user's state between Parent main flow's <-> subflows.
Debugging application logic placed inside webflow can be difficult. For instance, in webflow you can assign variables and perform condition checks all using SPEL inside the xml but this tends to be a pitfall. Over time you learn to avoid placing application logic inside the actual webflow xml and only use the xml to call service class methods and to place the returned values in the various scopes (again this hard learned lesson/best practice is undocumented). Also, because you are executing logic using SPEL... refactoring classes, method names, or variables sometimes silently break your application significantly increasing your development time.
初始化 SWF,以及与第三方框架集成,例如 Thymeleaf,是极其痛苦的。······。逻辑上调试应用也很困难。
fragment rendering... a powerful but unintuitive feature of webflow. Setting up fragment rendering was 1 of the most painful things I had to do with webflow. The documentation was lacking. I think this feature could easily go in the pros side if it was better documented and easy to setup. I actually documented how to use this feature via stackoverflow... How to include a pop-up dialog box in subflow.
(片段渲染?)...在 SWF 中是一个很强大的,但是反直觉的特性。
Static URLs per flow. If your flow has multiple views defined with in 1 flow your URL will not change navigating from view-state to view-state. This can be limiting if you want to control or match the content of the page with a dynamic url.
If your flow is defined in "/WEB-INF/flows/doSumTing/sumting-flow.xml" and your "base-path" is set to "WEB-INF/flows". Then to navigate to your flow you goto http://<your-host>/<your-webapp-name-if-defined>/doSumTing . The flow file name is completely ignored and not used in the URL at all. Although clear now I found this unintuitive when I first started.
每个流程的 URL 都是静态的。
# 优点
concept of "scope" containers flowScope, viewScope, flashScope, sessionScope and having easy access to these containers WITH IN A FLOW gives the developer flexibility as these are accessible from anywhere and are mutable.
scope 的概念,比如 flowScope, viewScope, flashScope, sessionScope,以及在一个流程中很容易的访问这些容器给予开发者很大的灵活性。
Easily define states view-state,action-state,decision-state,end-state which clearly defines what each state is doing but as mentioned in the cons... if your application is complex and has MANY different states and transitions constantly Going back and forth... this can clutter your -flow.xml file makes it hard to read or follow the sequential logic. It's only easy if you have simple use cases with a small number of state definitions.
状态很容易定义,在简单应用中。
Seldom used but a powerful feature of webflow is flow inheritance. Common flow functionality across multiple flows can be defined in a single abstract parent flow and extended by child flows (similar to an abstract class definition in java). This feature is nice with regards to the DRY principle if you have many flows that share common logic.
SWF有个很少使用但是很强大的一个功能——流程继承。
Easily defined validation rules and support for JSR-303 (but Spring MVC has this as well).
支持 JSR-303 。(译者注:JSR-303 Bean Validation)
The output tag can be used to send POJOs back and forth between Main flow <-> subflow. This feature is nice because the parameters don't need to be passed through the url via get/post and can pass as many POJOs as you wish.
output 标签可以在父流程和子流程之间传递 POJO。这很棒,意味着变量不需要通过 URL 或者 GET/POST 方法传送。
Clearly defined views. What the view name is and which model variable it is being mapped to (e.g <view-state id="edit" view="#{flowScope.modelPathName}/editView" model="modelObj">
). Also in the example just demonstrated can use preprocessing expressions for viewnames or most arguments in webflow... nice feature though not very well documented :/
定义视图很清晰。
# 作者总结
Spring Webflow project was a good idea and sounds great on paper but the cons make it cumbersome to work with in complex use cases increasing development time significantly. Since a better solution exists for complex use cases (Spring MVC) to me it is not worth investing heavily in web flow because you can achieve the same results with Spring MVC and with a faster development time for both complex and simple use cases. Morever, Spring MVC is actively maintained, has better documentation, and a larger user community. Maybe if some of my cons are addressed it would tip the scales in Webflow's favor but until then I will recommend Spring MVC over webflow.
SWF 表面上是个很好的主意,但是它很繁琐的缺点导致了在把它运用到大型项目时,显著的增加了工作时间。Spring MVC 相比于 SWF 显得更为优秀,因为 Spring MVC 开发的更快,而且适用于任何情况。 此外,Spring MVC 在文档和用户等方面更为活跃。我建议使用 Spring MVC 而不是 SWF。
# 译者的话
作者说优劣说的很清楚。其实想一想,简单的项目 Spring MVC 几行代码就完事了,简单的项目也不需要 SWF 啊。
我其实是反对 XML 的。一个项目要么全是 XML,要么全是源码,否则管理起来很麻烦。你看着源码,突然跳到 XML;看着 XML,突然跳到源码。这很容易分散注意力。迫不得已的情况下,使用 XML 才是正确的。
# Reference
http://stackoverflow.com/questions/29750720/what-are-the-spring-web-flow-advantages