该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2004-04-11
举一个常见的user 管理界面, 列出几个用户, 然后在用户旁边是delete和update的按钮, 先列出一个静态的html代码: <table> <tr> <td>User Name</td> <td>Action</td> </tr> <tr> <td>Quake Wang</td> <td><a href="#">Delete</a> <a href="#">Update</a></td> </tr> </table> 如果是基于jsp, 那么可能的最后代码是这个样子: <table> <tr> <td>User Name</td> <td>Action</td> </tr> <%while(users.hasNext(););{ User user = (User); users.next();;%> <tr> <td><%=user.getName();%></td> <td><a href="deleteUser?id=<%=user.getId();%>">Delete</a> <a href="updateUser?id=<%=user.getId();%>">Update</a></td> </tr> <%}%> </table> 如果是基于taglib, 和jsp差不多, 只是把hasNext(), next() 用foreach的标签替换掉, 把<%=%>, 用out标签替换掉. <table> <tr> <td>User Name</td> <td>Action</td> </tr> <c:forEach var="user" items="${users}"> <tr> <td><c:out value="${user.name}"/></td> <td><a href="deleteUser?id=<c:out value="${user.id}"/>">Delete</a> <a href="updateUser?id=<c:out value="${user.id}"/>">Update</a></td> </tr> </c:forEach> </table> 先不谈页面代码的支离破碎对于后期维护照成的困难, 觉得最麻烦的是需要用id传来传去, jsp, servlet上的传递参数到处都是, 破坏了原本优雅的OO代码. 我们来看看Tapestry是怎么处理的: <table> <tr> <td>User Name</td> <td>Action</td> </tr> <tr jwcid="@Foreach" source="ognl:users" element="tr" value="ognl:user"> <td><span jwcid="@Insert" value="ognl:user.name">Quake Wang</span></td> <td><a href="#" jwcid="@ActionLink" listener="ognl:listeners.deleteUser">Delete</a> <a href="#" jwcid="@ActionLink" listener="ognl:listeners.updateUser">Update</a></td> </tr> </table> 我们可以看到Tapestry不引入额外的语法, 它利用html的标签属性, 只要有jwcid(java web component id)属性和component需要的数据来源, 就能渲染出最终的html, 上面写好的模板可以直接在浏览器里面打开, 效果和最初的html代码是一样的, 这样就给后期维护页面带来了极大的方便. 在开发过程中, Tapestry带来最大的便利就是数据绑定, 我们看deleteUser的代码: public void deleteUser(IRequestCycle cycle); { getUserService();.deleteUser(getUser(););; } getUserService() 和 getUser()都是abstract method, tapestry会自动帮你做运行期增强, 我在实际开发中采用的是spring做service factory, 那么给userService一个初始值, 让它从service locator里面获取: <property-specification name="userService" type="com.abc.ent.service.UserService" initial-value="global.serviceManager.userService"/> getUserService() 这个方法就会获得这个userService, 而getUser()则是Tapestry会自动获得绑定的user. 可以看到同jsp相比, 用Tapestry实现的代码非常的简单. 我最近在学习Tapestry的架构, 被它的先进的想法所深深吸引, 如果论坛上有谁对此有研究, 请多多交流. 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2004-04-12
提个建议,这个话题看看能不能扩展。大家就自己知道的表现层框架,给出同样这个问题的不同答案。好好的比较一下。
|
|
返回顶楼 | |
发表时间:2004-04-12
在开发的过程中, Tapestry给我带来的最大方便就是可以换个角度写代码, 可以完全抛弃在原来page by page的MVC架构中需要使用id传来传去这种无趣的做法,every thing is Object, 至于页面上的整洁和易维护性只是它的天然优势之一。
它的缺点:文档太少,不看原代码的话, 只有它的example可以抄,但是我们知道example做demo还可以, 但是运用到真正的项目中, 就得考虑最佳实践 (best practice)了, 很多时候都得深入到代码, 才能发现, 哦,原来有这么方便的写法。 这点估计等到用的人多了,才会有所改善吧。 |
|
返回顶楼 | |
发表时间:2004-04-13
Quake Wang 写道 在开发的过程中, Tapestry给我带来的最大方便就是可以换个角度写代码, 可以完全抛弃在原来page by page的MVC架构中需要使用id传来传去这种无趣的做法,every thing is Object, 至于页面上的整洁和易维护性只是它的天然优势之一。
它的缺点:文档太少,不看原代码的话, 只有它的example可以抄,但是我们知道example做demo还可以, 但是运用到真正的项目中, 就得考虑最佳实践 (best practice)了, 很多时候都得深入到代码, 才能发现, 哦,原来有这么方便的写法。 这点估计等到用的人多了,才会有所改善吧。 有同感,现在都熟悉Howard M. Lewis Ship的代码风格了 |
|
返回顶楼 | |
发表时间:2004-04-13
确实资料文档比较少,
而且spindle这个插件做的不怎么好,没有做到拖拉组件的功能。 |
|
返回顶楼 | |
发表时间:2004-04-14
从你的例子举的不好,不是taglib的用法.
最近用tapstrey的项目接近收尾了.自己的感觉是:它不是什么银弹,分离不了页面和程序. 1,就如你举的例子,做页面的mm是不会自己加jwcid="@Foreach",也不会自己加taglib.对于程序人员来讲,加jwcid和使用taglib是一样的工作量. 2,增加隐藏变量的问题,tapstrey同样的也有.我是没有避免,不知道你怎么做的.不使用的话,自动使用缺省值. 3,到处都是参数的问题,实际上是页面form参数和oo(tapstrey),formbean(struts)自动映射的问题. 4,数据绑定,tapstrey的oo,就如struts的formbean一样. 5,工具支持,没有一个好的ide,tapstrey难用的很,java,page,html之间有大量的对应关系.就和hibernate的配置文件一样,如果不能自动完成同步,在一个稍微大点的项目中就会带来巨大的工作量. 6,组件,在我看来tapstrey最大的好处就是组件库,这些组件大大简化了编程.但问题是组件的灵活性和数量.这和taglib也一样. 在我看来,tapstrey要想兴旺发达,1,一个快速的ide,2,丰富的组件库. 我的下一个项目估计是不会用tapstrey了.还是用struts,但struts最烦的是formbean的紧密结合,另,实际上dw早就有支持taglib的插件了,只不过因为页面mm从来不用. 但真正分离页面和程序,恐怕还有很远的路要走,但不会是现在的tapstrey. |
|
返回顶楼 | |
发表时间:2004-04-14
youcai 写道 实际上dw早就有支持taglib的插件了,只不过因为页面mm从
推荐一下好吗? |
|
返回顶楼 | |
发表时间:2004-04-14
ultradev4 plug in ?这个?
|
|
返回顶楼 | |
发表时间:2004-04-14
youcai 写道 从你的例子举的不好,不是taglib的用法. 我把最初的帖子修改了一下, 加上了taglib的写法, 不知道你说的不是taglib的写法是什么意思? youcai 写道 1,就如你举的例子,做页面的mm是不会自己加jwcid="@Foreach",也不会自己加taglib.对于程序人员来讲,加jwcid和使用taglib是一样的工作量. 2,增加隐藏变量的问题,tapstrey同样的也有.我是没有避免,不知道你怎么做的.不使用的话,自动使用缺省值. 3,到处都是参数的问题,实际上是页面form参数和oo(tapstrey),formbean(struts)自动映射的问题. 4,数据绑定,tapstrey的oo,就如struts的formbean一样. 关于Tapestry能否带来页面和代码的分离, 以及能否提供页面设计人员和维护人员的工作效率, 论坛里面已经讨论很多了, 我不想把这个帖子又转到这方面上. 我们来讨论一下对于程序开发以及维护人员的帮助: 你看一下我最上面的例子, Tapestry没有用id来传递, 而是把users这个source用Foreach组件生成的user对象绑定到ActionLink这个组件上, 当它被点击的时候, 触发listener, listener方法只用getUser(), 就可以获得绑定的user, 从而进行对应的操作. 从这个单个的传递id的例子, 我们可能还看不出来Object binding的威力. 再举一个常见的例子, 比如用户管理模块里面, 我们需要把某个user加入到一个group里面, 基于jsp, taglib的做法是需要传递userId和groupId (可能是通过link里面的parameter或者是hidden value), 而用户在这个页面上操作的时候, 必然已经是看到了group和user这些对象了,我们只用绑定这些对象到组件, 后台程序只用一句调用逻辑Service的代码就可以了: public void addUserToGroup(IRequestCycle cycle); { getUserService();.addUserToGroup(getUser();, getGroup(););; } getUserService() 通过page定义得初始值, 从Global Service Locator获取UserService的implement. getUser()和getGroup() 通过Tapestry自动的类增强功能获取绑定在这个促发这个lisenter组件上的user和group对象. 这样不是很简洁吗? 至少目前我的项目中是没有出现传递id参数的代码. 如果你的项目当中有那么多的传递参数的话, 是没有好好用到Tapestry的数据绑定的特性吧? 我一开始接触Tapestry的时候, 也是用原有基于jsp/taglib那种page by page的思想在看, 学会Object Binding以后觉得Tapestry在这点上帮我少写了好多dirty code, . youcai 写道 5,工具支持,没有一个好的ide,tapstrey难用的很,java,page,html之间有大量的对应关系.就和hibernate的配置文件一样,如果不能自动完成同步,在一个稍微大点的项目中就会带来巨大的工作量. 6,组件,在我看来tapstrey最大的好处就是组件库,这些组件大大简化了编程.但问题是组件的灵活性和数量.这和taglib也一样. 你有没有试过Spindle? 非常好用的Tapestry eclipse plugin. 写了一些UI组件和业务组件, 觉得Tapestry的组件比taglib要灵活, 主要是有它的Object Binding特性做支持, 组件重用性会很高. |
|
返回顶楼 | |
发表时间:2004-04-14
感觉TAPESTRY最大的优点就是组件化和OO,至于让美工MM改代码。。。从来没想过,现在公司里有N多程序员却只有一个美工。
以前做过一个XML+XSL的项目,美工在花费一定时间学习掌握XSL后,我们得到反馈非常好,尤其是做几个不同风格的页面不需要修改一行JAVA代码,只做XSL就OK了,这是我做过的页面与代码分离的最好的架构。可惜的是XML解析效率不高。。。我们的WEBMAIL不得不过一段时间重启一下 |
|
返回顶楼 | |