Tapestry5的介绍文章

Introduction

There's no getting around it ... Struts is the 800lb gorilla of Java web application frameworks. It was on the scene early, it got wide coverage and wide adoptions, and vast numbers of applications have been written in it.

Struts is an action based framework, and exists as a kind of thin wrapper on top of the base Servlet API. This is good as far as it goes, but Tapestry has always existed as an example of why that view of the world is limited.

Tapestry, especially Tapestry 5, represents a somewhat radical approach compared to Struts. You will find it to be quite compelling ... but it also requires adjusting your mindset to a completely different way of looking at building web applications.

这个是重点。相当互补,同时需要转变思维。

Struts: Actions and Views

Tapestry and Struts approach the division of concerns represented by the Model-View-Controller design pattern from very different angles.

Struts maps incoming URLs to actions; these actions are objects that extends from the Action base class.

What does an action do? It reads query parameters in the request either directly, or via an associated ActionForm object. It probably talks to your backend to read information from a database, or write information out to it. It probably stores some information in the request, information that will be needed by the view when it renders. Finally, it returns the name of the view.

The framework picks it up from there; it uses that view name to select a template, usually a JavaServer page, and gets the template to render a response to the user.

How does Struts find all this? Lots of XML configuration; endless details for each and every "page" to define the controller class, the map view names to JSPs, to link views and actions to ActionForm classes

这确实就是WEB开发的实质。解析Request,调用服务器方法,返回输出结果。当然,并不一定是要按照Struts的方式实现。.

The Problem of Statelessness

Where does Struts (and similar frameworks) get things wrong? The first issue is with the management of state.

Remember "Beginning Object Oriented Programming 101"? Objects are generally defined as a software construct that encapsulates behavior and state.

Struts actions do not have internal state. They can't -- they're singletons, one instance shared by however many threads are operating within the servlet container. Any internal state, which is to say, any instance variables, would be immediately overwritten by some other thread servicing a request for some other user.

Struts approaches this problem by externalizing state: into the HttpServletRequest (for state needed just by the view), or into the HttpSession (for state that must persist from one request to the next).

Basically, what we have here is a crippled form of object oriented programming: objects that have a single behavior, and have no internal state.

As we'll see, Tapestry addresses both of these issues: in Tapestry, components can have internal state, and they may have not just one, but many different behaviors.


保守攻击的一点:因为Action是单实例的线程模型,同一个实现被多个线程所访问,那么就不允许在实例中有局部变量。说道OO,就相当与说不允许对象中存在内部状态,这确实是和OO背离的。

Views: An Artifical Barrier

Action frameworks create a separation between the behavior logic, the code inside a Struts Action, and the view logic, which it typically a JavaServer Page.

The artificial barrier is the lack of linkage between the template and the controller (the Struts Action). The only line of communication is the data in the HttpServletRequest and HttpSession.

There's a purpose to this design: it's all about the choice for the view. Because the action may select one of several views, it's necessary to loosely couple the action and the view. The HttpServletRequest, and the named attributes stored in the request, is the form of this loose coupling.

This puts an onus on the action to stuff into the HttpServletRequest any and all data that might be needed by the view as it renders a response. After all, there's no other alternative, is there?

Additionally, there's the issue of getting the action and the view, or views, to agree on the name and type of every bit of state stored inside the HttpServletRequest or HttpSession. Small changes to the controller, such as storing a different piece of data, or using a different name, can have a ripple effect inside the view.

This makes sense, doesn't it? After all, the result of an action (such as clicking a link or submitting a form) may be some kind of success, or some kind of error. Or perhaps you decide on the flavor of output based on the kind of client: HTML for the desktop or WML for a phone.

Perhaps in theory, but certainly not in practice. Errors are rarely presented as a whole new view; they are usually presented as additional content within the same view. As to the myth of a single application that vends out different markups for different clients ... that is just a myth. It's not just about output, but about every aspect of application development. It's more than just what content shows up where ... it's about the very functionality offered and the use cases supported, which are very different from one device to another. Pull back the covers on any single application that supports such diverse clients and you'll find multiple applications, one per device type, squeezed together as a not-so-coherent package.


VIEW:是从page,request,session,application的范围中取得所需要的数据。Action将这些显示VIEW所需要的数据都放在这些Scope的变量中去,使得View和Action截耦合了。但这就必须要约定说比如说变量的命名台等

 

Components: Its Not Just About Output

What happens when you have common fixtures to your application? By fixtures, we mean, bits of the view that are used in many places throughout the application. This includes large chunks of functionality, such as a menu system used on every page, down to tiny bits of functionality, like some kind of "widget" to format a date for output.

JSPs provide two approaches for this kind of behavior: you can use JSP includes, to reuse JSPs snippets across many larger JSPs. Alternately, you can define and use JSP tags, which provide a way to generate output using code, and provides mechanism for passing information from the HttpServletRequest into the JSP tag implementation. Alas, in the real world, the vast majority of actions do have just a single view, named "success" by convention. After all, even when an error occurs, you don't want to lose all context ... if a user enters incorrect information into a form, then you want to redisplay the form with the error messages. The view has to adapt to the state determined by the request.

But what happens when the "fixture" has its own behavior? It's own state?

For example, maybe a fixture is a login form that's displayed on every page until the user logs in. The form may have a URL that points to a login Action ... but how do you return to the same view after logging in? A similar case may be a component that displays tabular data and supports paging. Such a component will have links for navigation and sorting. How do the actions for those links return the user to the same view after changing the set of displayed items? What if there's more than one such component in a single view?

You end up writing more and more configuration and boilerplate code. You must define more and more JSP attributes or other tricks in order to tell the appropriate action how to get the correct view after performing the actions.

You've run into the limitation of not having true web components on your side.

With Tapestry, individual components can have their own interactions, blended seamlessly into the page, even when the same component is used across multiple pages. Tapestry is able to keep everything organized because it has its own view of the application, the component object model.

自己的应用程序的View:componet object model?


Tapestry: The Full Cycle Solution

What Tapestry offers is structure. A well defined, fixed structure of pages and components within pages. This structure is used in every aspect of Tapestry, including state management, output rendering, and request dispatching.

You don't have to worry about URLs. Incoming requests for Tapestry encode the name of the page and the id of the component within the page, along with other information, into the URL for you. Your code never has to pick apart a URL, you create event listening methods to know when the user has clicked a link or submitted a form, or done something more interesting using Ajax. Tapestry has the structure it needs to build all necessary information into the URL, and unpack that information in a later request.

Tapestry is truly object oriented: you don't have to be concerned with singletons and multithreading; your pages and components have instance variables like any other plain Java object. Tapestry lets your write your application using true object oriented techniques.

In terms of state management: Tapestry takes care of persisting field values into the session. You don't have to figure out mneumonic, unique names for session attributes, or write code to pull data out of the session or push it back in. Tapestry is able to do this for you.

Further, in Tapestry pages and components are identical. They are consistent. Pages have templates, so do components. Pages have transient and persistent fields. So do components. Pages have event handler methods, so do components.

Tapestry doesn't have the idea of multiple views for a single page. However, processing within one page can easily "hand off" to another page, in Java code, to provide the response to an action by the user.

Making the Transition

我看这个是这篇文章想要说的。

Don't expect there to be a magic tool to convert an existing application to Tapestry 5. The worlds between Struts and other action oriented frameworks, and Tapestry, are just too far.

With Tapestry, you can start to think of your application in the same terms as your users ... as a collection of pages that are connected together.

You don't create URLs and map them to singleton classes; you put a component in your page, and add an event handling method to your class to be invoked when that component is triggered. Many components? No problem, just add more event handler methods.

Leave Behind the Pain

Tired of constantly rebuilding and redeploying your application every time you make a change? Tapestry features live class reloading. Every time you make a change to your code or your templates, Tapestry picks up the changes immediately ... no waiting! Just think about how fast and easy building an application is without the expected constraints; scripting language speed with all the power of Java.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值