论坛首页 软件开发和项目管理版 敏捷开发

什么样的开发才算快速开发

浏览 17171 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
最后更新时间:2006-04-12
很长一段时间以来,不停的听到快速开发的概念,究竟快速到什么程度才算快速开发呢?
以典型的检索系列画面为例,
引用

检索条件画面
1:用户可以输入n个可选检索条件,如果有输入则加上对应的检索条件,如果不输入则无视该检索条件
2:条件包括 =,<, >, like等及其组合
3:可能存在的式样变更 添加/删除可选检索条件,条件逻辑例如=,like之间的切换
检索逻辑
1:为了简单起见,从单个View里面检索
2:可能存在的式样变更 增加/减少检索字段
检索结果一览画面
1:一览显示,

这里暂时不考虑美工的工作量,即两个画面都已经有现成的HTML文件了,那么对于这么样的一个需求,两个画面一个业务处理,达到怎么样的一个开发速度才算快速开发呢?
(希望能看到大家拿数字说话,而不是含糊其辞的高空理论)
   
最后更新时间: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)。
   
0 请登录后投票
最后更新时间: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方式输出。。。

太理想叻,哈哈
   
0 请登录后投票
最后更新时间:2006-04-13
...没有让你们设计界面啊  页面在好看,在AJAX,

查询条件组合处理才是最重要的吧

不知道所谓开发速度是指什么?  想要什么数字? 几天开发完?

我觉得这里面如何检索才是最关键的,但是很难估算出来吧
   
0 请登录后投票
最后更新时间:2006-04-13
jkit 写道
很长一段时间以来,不停的听到快速开发的概念,究竟快速到什么程度才算快速开发呢?
以典型的检索系列画面为例,
引用

检索条件画面
1:用户可以输入n个可选检索条件,如果有输入则加上对应的检索条件,如果不输入则无视该检索条件
2:条件包括 =,<, >, like等及其组合
3:可能存在的式样变更 添加/删除可选检索条件,条件逻辑例如=,like之间的切换
检索逻辑
1:为了简单起见,从单个View里面检索
2:可能存在的式样变更 增加/减少检索字段
检索结果一览画面
1:一览显示,

这里暂时不考虑美工的工作量,即两个画面都已经有现成的HTML文件了,那么对于这么样的一个需求,两个画面一个业务处理,达到怎么样的一个开发速度才算快速开发呢?
(希望能看到大家拿数字说话,而不是含糊其辞的高空理论)


用我们的公用类库大概半天不到可以做出来,但是公用类库的开发花了很长时间……
   
0 请登录后投票
最后更新时间: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]
   
0 请登录后投票
最后更新时间:2006-04-13
不如大家都把自己完整的project代码贴出来吧,看看究竟谁的真正快速而且易用。
   
0 请登录后投票
最后更新时间:2006-04-13
我觉得这个上面无论是10分钟,还是1个小时,都没有什么太大的区别。
   
0 请登录后投票
最后更新时间:2006-04-13
robbin 写道
不如大家都把自己完整的project代码贴出来吧,看看究竟谁的真正快速而且易用。
期待中...
   
0 请登录后投票
最后更新时间: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]

以上代码都是代码生成器生成的。
   
0 请登录后投票
论坛首页 软件开发和项目管理版 敏捷开发

跳转论坛:
JavaEye推荐