|
锁定老贴子 主题:什么样的开发才算快速开发
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
最后更新时间:2006-04-12
很长一段时间以来,不停的听到快速开发的概念,究竟快速到什么程度才算快速开发呢?
以典型的检索系列画面为例, 引用 检索条件画面 1:用户可以输入n个可选检索条件,如果有输入则加上对应的检索条件,如果不输入则无视该检索条件 2:条件包括 =,<, >, like等及其组合 3:可能存在的式样变更 添加/删除可选检索条件,条件逻辑例如=,like之间的切换 检索逻辑 1:为了简单起见,从单个View里面检索 2:可能存在的式样变更 增加/减少检索字段 检索结果一览画面 1:一览显示, 这里暂时不考虑美工的工作量,即两个画面都已经有现成的HTML文件了,那么对于这么样的一个需求,两个画面一个业务处理,达到怎么样的一个开发速度才算快速开发呢? (希望能看到大家拿数字说话,而不是含糊其辞的高空理论) 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
最后更新时间:2006-04-12
jkit 写道 很长一段时间以来,不停的听到快速开发的概念,究竟快速到什么程度才算快速开发呢?
以典型的检索系列画面为例, 引用 检索条件画面 1:用户可以输入n个可选检索条件,如果有输入则加上对应的检索条件,如果不输入则无视该检索条件 2:条件包括 =,<, >, like等及其组合 3:可能存在的式样变更 添加/删除可选检索条件,条件逻辑例如=,like之间的切换 检索逻辑 1:为了简单起见,从单个View里面检索 2:可能存在的式样变更 增加/减少检索字段 检索结果一览画面 1:一览显示, 这里暂时不考虑美工的工作量,即两个画面都已经有现成的HTML文件了,那么对于这么样的一个需求,两个画面一个业务处理,达到怎么样的一个开发速度才算快速开发呢? (希望能看到大家拿数字说话,而不是含糊其辞的高空理论) 这是一个标准的动态条件查询,如果是我的话,这两个画面会放在一个页面里面完成,上面是查询条件,下面是查询结果,上面查询条件提交以后,XMLHTTP请求,返回HTML动态替换下面的DIV内容。 底层框架是最流行的Hibernate/Spring/Webwork组合,脚手架代码我有现成的,就是写一个domain object,配一下hbm,继承一个BaseDaoImpl,写两个Webwork Action,两个FTL页面。动态条件在Web Action里面用Hibernate的DetachedCriteria组装,参数送到后面,直接就出来。如果页面模板已经事先做好,我想我大概1小时搞定(包括TestCase)。 |
|
| 返回顶楼 | |
|
最后更新时间:2006-04-13
robbin 写道 这是一个标准的动态条件查询,如果是我的话,这两个画面会放在一个页面里面完成,上面是查询条件,下面是查询结果,上面查询条件提交以后,XMLHTTP请求,返回HTML动态替换下面的DIV内容。 底层框架是最流行的Hibernate/Spring/Webwork组合,脚手架代码我有现成的,就是写一个domain object,配一下hbm,继承一个BaseDaoImpl,写两个Webwork Action,两个FTL页面。动态条件在Web Action里面用Hibernate的DetachedCriteria组装,参数送到后面,直接就出来。如果页面模板已经事先做好,我想我大概1小时搞定(包括TestCase)。 如果这样实现呢? 还是一样的脚手架,只需要一个Action、一个Service和一个HTML页面。 在HTML页面上面显示查询form,下面显示结果,结果内容的模板使用TrimPath来写。当form被以AJAX方式提交后,后台Action构造Hibernate的DetachedCriteria传给后面将数据查询出来,这个数据是一个List,里面的数据是Domain Object(POJO),然后WebWork返回我Scaffold2里那个JavaScript Object View Result,将Domain Object的list()以JavaScript对象方式输出,传回HTML页面,HTML拿到JavaScript对象,将数据模型传给TrimPath,根据TrimPath模板构造出结果html内容,用innerHTML方式输出。。。 太理想叻,哈哈 |
|
| 返回顶楼 | |
|
最后更新时间:2006-04-13
...没有让你们设计界面啊 页面在好看,在AJAX,
查询条件组合处理才是最重要的吧 不知道所谓开发速度是指什么? 想要什么数字? 几天开发完? 我觉得这里面如何检索才是最关键的,但是很难估算出来吧 |
|
| 返回顶楼 | |
|
最后更新时间:2006-04-13
jkit 写道 很长一段时间以来,不停的听到快速开发的概念,究竟快速到什么程度才算快速开发呢?
以典型的检索系列画面为例, 引用 检索条件画面 1:用户可以输入n个可选检索条件,如果有输入则加上对应的检索条件,如果不输入则无视该检索条件 2:条件包括 =,<, >, like等及其组合 3:可能存在的式样变更 添加/删除可选检索条件,条件逻辑例如=,like之间的切换 检索逻辑 1:为了简单起见,从单个View里面检索 2:可能存在的式样变更 增加/减少检索字段 检索结果一览画面 1:一览显示, 这里暂时不考虑美工的工作量,即两个画面都已经有现成的HTML文件了,那么对于这么样的一个需求,两个画面一个业务处理,达到怎么样的一个开发速度才算快速开发呢? (希望能看到大家拿数字说话,而不是含糊其辞的高空理论) 用我们的公用类库大概半天不到可以做出来,但是公用类库的开发花了很长时间…… |
|
| 返回顶楼 | |
|
最后更新时间:2006-04-13
[quote="robbin"][quote="jkit"]很长一段时间以来,不停的听到快速开发的概念,究竟快速到什么程度才算快速开发呢?
以典型的检索系列画面为例, [quote] 检索条件画面 1:用户可以输入n个可选检索条件,如果有输入则加上对应的检索条件,如果不输入则无视该检索条件 2:条件包括 =,<, >, like等及其组合 3:可能存在的式样变更 添加/删除可选检索条件,条件逻辑例如=,like之间的切换 检索逻辑 1:为了简单起见,从单个View里面检索 2:可能存在的式样变更 增加/减少检索字段 检索结果一览画面 1:一览显示, [/quote] 这里暂时不考虑美工的工作量,即两个画面都已经有现成的HTML文件了,那么对于这么样的一个需求,两个画面一个业务处理,达到怎么样的一个开发速度才算快速开发呢? (希望能看到大家拿数字说话,而不是含糊其辞的高空理论)[/quote] 这是一个标准的动态条件查询,如果是我的话,这两个画面会放在一个页面里面完成,上面是查询条件,下面是查询结果,上面查询条件提交以后,XMLHTTP请求,返回HTML动态替换下面的DIV内容。 底层框架是最流行的Hibernate/Spring/Webwork组合,脚手架代码我有现成的,就是写一个domain object,配一下hbm,继承一个BaseDaoImpl,写两个Webwork Action,两个FTL页面。动态条件在Web Action里面用Hibernate的DetachedCriteria组装,参数送到后面,直接就出来。如果页面模板已经事先做好,我想我大概1小时搞定(包括TestCase)。[/quote] 不好意思,我这边开发这个东东一般性的都不会超过10m。 我提供了一个查询模块 条件通过xml配置; [code:1] <search name="product" class="org.commonfarm.model.Product" url="productAction.do"> <item name="code" type="string" mode="like" /> <item name="name" type="string" mode="like" /> <item name="catId" type="string" mode="like" association="category"/> </search> [/code:1] 然后写一个条件输入的页面以及数据显示的页面(下边是在一起的) [code:1] <%@ include file="/pages/common/taglibs.jsp"%> <!-- Search Criteria --> <div id="search"> <html:form action="productAction"> <table class="simple"> <tr> <th>Code</th> <td><html:text property="s_code" /></td> <th>Name</th> <td><html:text property="s_name" /></td> <th>Category</th> <td><common:popup property="s_catId" function="Category" open="productCategoryAction" window="CategoryPicker" /></td> </tr> <tr> <td colspan="6"> <input type="submit" value=" Search " name="search">& <input type="reset" value=" Reset " name="reset" > </td> </tr> </table> </html:form> </div> <!-- Pagination --> <%if (request.getAttribute("page") != null) {%> <%=request.getAttribute("page")%> <%}%> <!-- Search List (DETAIL) --> <display:table name="list" class="simple"> <display:column property="code" /> <display:column property="name" /> <display:column property="category.catId" /> <display:column property="category.name"/> <display:column property="unitPrice" /> <display:column property="priceUnit" /> </display:table> [/code:1] Action需要继承BaseAction,代码不需要多写 需要配置一下tiles 需要在ActionForm中添加查询条件的属性[/quote] |
|
| 返回顶楼 | |
|
最后更新时间:2006-04-13
不如大家都把自己完整的project代码贴出来吧,看看究竟谁的真正快速而且易用。
|
|
| 返回顶楼 | |
|
最后更新时间:2006-04-13
我觉得这个上面无论是10分钟,还是1个小时,都没有什么太大的区别。
|
|
| 返回顶楼 | |
|
最后更新时间:2006-04-13
robbin 写道 不如大家都把自己完整的project代码贴出来吧,看看究竟谁的真正快速而且易用。 期待中...
|
|
| 返回顶楼 | |
|
最后更新时间:2006-04-13
我贴份我的一部分。
(目前的代码生成是生成ssh的,过段时间会生成的ajax的。) 现说下步骤: 1.pd里建立cdm。 2.根据cdm声称hbm文件, 3.根据hbm文件生成所有的java代码和jsp,以及配置文件。 (一张表作为一个模块) hbm: [code:1] <?xml version="1.0" encoding='UTF-8'?> <hibernate-mapping package="net.share_info.blogpro.hibernate"> <!-- 友情连接。 --> <class name="BlogLink" table="BLOGLINK" node="友情博客连接" optimistic-lock="version"> <id name="linkNo" column="LINKNO" node="连接编号" type="java.lang.String" length="40" > <generator class="assigned"/> </id> <version name="version" column="VERSION" node="version" type="java.lang.Integer"/> <property name="addtime" column="ADDTIME" type="java.util.Date" node="addtime"/> <property name="blogUserName" column="BLOGUSERNAME" node="博客用户名" type="java.lang.String" not-null="true" length="40" /> </class> </hibernate-mapping> [/code:1] pojo和myeclipse生成的代码差不多: [code:1] public class AbstractBlogLink implements Serializable { private int hashValue = 0; private java.lang.String linkNo; // 连接编号 private java.lang.Integer version = new Integer(0); // version private java.util.Date addtime; // addtime private java.lang.String blogUserName; // 博客用户名 public java.lang.String getLinkNo() { return this.linkNo; } public void setLinkNo(java.lang.String linkNo) { this.hashValue = 0; this.linkNo = linkNo; } public void setBlogUserName(java.lang.String blogUserName) { this.blogUserName = blogUserName; } public java.lang.String getBlogUserName() { return blogUserName == null ? "" : this.blogUserName; } [/code:1] dao一个find方法: [code:1] public List findBlogLinkby( final java.lang.String linkNo, final java.util.Date addtime_begin, final java.util.Date addtime_end, final java.util.Date lastupdatetime_begin, final java.util.Date lastupdatetime_end, final java.lang.String blogUserName, final java.lang.String linkTitle, final java.lang.String htmlHref, final java.lang.String xmlHref, final java.lang.String linkCat, final java.lang.String isShow, final Pagination page){ return (List)this.getHibernateTemplate().execute( new HibernateCallback() { public Object doInHibernate(Session session) throws SQLException, HibernateException { Criteria ca = session.createCriteria(BlogLink.class); if (linkNo != null && linkNo.length() > 0) { ca.add(Expression.like("linkNo", linkNo, MatchMode.ANYWHERE)); } if (addtime_begin != null) { ca.add(Expression.ge("addtime", addtime_begin)); } if (addtime_end != null) { ca.add(Expression.le("addtime", addtime_end)); } if (lastupdatetime_begin != null) { ca.add(Expression.ge("lastupdatetime", lastupdatetime_begin)); } if (lastupdatetime_end != null) { ca.add(Expression.le("lastupdatetime", lastupdatetime_end)); } if (blogUserName != null && blogUserName.length() > 0) { ca.add(Expression.like("blogUserName", blogUserName, MatchMode.ANYWHERE)); } if (linkTitle != null && linkTitle.length() > 0) { ca.add(Expression.like("linkTitle", linkTitle, MatchMode.ANYWHERE)); } if (htmlHref != null && htmlHref.length() > 0) { ca.add(Expression.like("htmlHref", htmlHref, MatchMode.ANYWHERE)); } if (xmlHref != null && xmlHref.length() > 0) { ca.add(Expression.like("xmlHref", xmlHref, MatchMode.ANYWHERE)); } if (linkCat != null && linkCat.length() > 0) { ca.add(Expression.like("linkCat", linkCat, MatchMode.ANYWHERE)); } if (isShow != null && isShow.length() > 0) { ca.add(Expression.like("isShow", isShow, MatchMode.ANYWHERE)); } page.setTotalNum(((Integer) ca.setProjection(Projections. rowCount()).uniqueResult()).intValue()); ca.setProjection(null); ca.setMaxResults(page.getPageSize()); ca.setFirstResult(page.getStartIndex()); return ca.list(); } }, true); } [/code:1] struts form的validator: [code:1] <!-- i18n --> <formset > <form name="blogLinkEditActionForm"> <field property="blogLinkVO.linkNo" depends="required"> <arg key="连接编号" position="0" resource="false"/> </field> <field property="blogLinkVO.blogUserName" depends="required"> <arg key="博客用户名" position="0" resource="false" /> </field> <field property="blogLinkVO.blogUserName" depends="maxlength"> <arg key="博客用户名" position="0" resource="false" /> <arg key="${var:maxlength}" position="1" resource="false"/> <var> <var-name>maxlength</var-name> <var-value>40</var-value> </var> </field> [/code:1] struts-config [code:1] <struts-config> <form-beans> <form-bean name="blogLinkEditActionForm" type="com.codeutil.sample.bloglinkman.BlogLinkEditActionForm" /> <form-bean name="blogLinkSearchActionForm" type="com.codeutil.sample.bloglinkman.BlogLinkSearchActionForm" /> </form-beans> <action-mappings> <action input="/blogman/bloglinkman/indexBlogLink.jsp" name="blogLinkSearchActionForm" path="/blogman/bloglinkman/blogLinkIndexAction" scope="request" type="org.springframework.web.struts.DelegatingActionProxy"> <forward name="indexBlogLink" path="/blogman/bloglinkman/indexBlogLink.jsp" /> </action> [/code:1] spring [code:1] <!--com.codeutil.sample.bloglinkman.IBlogLinkDAO --> <bean id="iBlogLinkDAO" class="com.codeutil.sample.bloglinkman.impl.BlogLinkHibernateDAO" singleton="true" lazy-init="true" > <property name="sessionFactory"> <ref bean="mainSessionFactory"/> </property> </bean> <!--com.codeutil.sample.bloglinkman.IBlogLinkLogic --> <bean id="iBlogLinkLogic" parent="baseTxProxy"> <property name="target"> <bean class="com.codeutil.sample.bloglinkman.impl.BlogLinkLogicImpl" singleton="true" lazy-init="true"> <property name="varIBlogLinkDAO"> <ref local="iBlogLinkDAO"/> </property> </bean> </property> </bean> <bean name="/blogman/bloglinkman/blogLinkIndexAction" class="com.codeutil.sample.bloglinkman.BlogLinkIndexAction"> <property name="varIBlogLinkLogic"> <ref local="iBlogLinkLogic"/> </property> </bean> [/code:1] jsp: 查询条件(属性名已经存放到资源文件中以支持i18n): [code:1] <fmt:message key="linkNo" bundle="${resBlogLink}" />:<html:text property="linkNo" /> <br/>-----------<br/> <fmt:message key="addtime" bundle="${resBlogLink}" />:<html:text property="addtime_begin" /> <br/> <fmt:message key="addtime" bundle="${resBlogLink}" />:<html:text property="addtime_end" /><br/> <fmt:message key="lastupdatetime" bundle="${resBlogLink}" />:<html:text property="lastupdatetime_begin" /> <br/> <fmt:message key="lastupdatetime" bundle="${resBlogLink}" />:<html:text property="lastupdatetime_end" /><br/> <fmt:message key="blogUserName" bundle="${resBlogLink}" />:<html:text property="blogUserName" /> <br/> <fmt:message key="linkTitle" bundle="${resBlogLink}" />:<html:text property="linkTitle" /> <br/> <fmt:message key="htmlHref" bundle="${resBlogLink}" />:<html:text property="htmlHref" /> <br/> <fmt:message key="xmlHref" bundle="${resBlogLink}" />:<html:text property="xmlHref" /> <br/> <fmt:message key="linkCat" bundle="${resBlogLink}" />:<html:text property="linkCat" /> <br/> <fmt:message key="isShow" bundle="${resBlogLink}" />:<html:text property="isShow" /> <br/> [/code:1] 查询结果显示: [code:1] <FIELDSET><LEGEND>search result </LEGEND> <display:table name="requestScope.loginLogList" id="blogLinkTable" pagesize="20" partialList="true" size="totalNum"> <fmt:setBundle basename="net.share_info.blogpro.hibernate.localstring.BlogLink" /> <display:column property="loginTime" /> <display:column property="linkNo" titleKey="linkNo" /> <display:column property="addtime" titleKey="addtime" /> <display:column property="lastupdatetime" titleKey="lastupdatetime" /> <display:column property="blogUserName" titleKey="blogUserName" /> <display:column property="linkTitle" titleKey="linkTitle" /> <display:column property="htmlHref" titleKey="htmlHref" /> <display:column property="xmlHref" titleKey="xmlHref" /> <display:column property="linkCat" titleKey="linkCat" /> <display:column property="isShow" titleKey="isShow" /> </display:table> </FIELDSET> <!--顺便套上了js对表格内容排序---> <script type="text/javascript"> var st = new SortableTable( document.getElementById("blogLinkTable"), ["String", "String", "String", "String", "String", "String", "String", "String", "String" ,"None","None"]); </script> <c:if test="${not empty(actionMsg)}"> <script type="text/javascript"> window.alert("<fmt:message key="${actionMsg}" bundle="${resBlogLink}" />"); </script> </c:if> [/code:1] 以上代码都是代码生成器生成的。 |
|
| 返回顶楼 | |














