发展,需求驱动 · 一间 所见即所得
从需求不是一句空话。同样是在发展过程中真正的。
需求驱动,与极限编程的一些想法和测试驱动开发基本重合。
鉴于该网站的发展是一个比较流行的方向,我会从网站开始,阐述自己的“需求驱动的发展“认识,并扩展到更广泛的领域。
首先,我们如果一个需求:
我们须要实现一个类似google的站点,用户通过web浏览器訪问,在首页输入框中查询。返回搜索的结果。
效果例如以下图所看到的:
STEP 0,通过eclipse创建一个web项目:sitefromscratch。文件结构如图所看到的:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGVsdGF0YW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
在WebRoot下新增一个jsp文件:
<%@ page pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head> <body>
<h1>search it!</h1> <form action="" method="get">
<input type="text" value="site from scratch" name="keywords" />
<input type="submit" value="search!" />
</form> <table border="1" bordercolor="grey" >
<tr>
<td>result 1</td><td>something..................</td>
</tr>
<tr>
<td>result 1</td><td>something..................</td>
</tr>
<tr>
<td>result 1</td><td>something..................</td>
</tr>
<tr>
<td>result 1</td><td>something..................</td>
</tr>
</table> </body>
</html>
通过浏览器訪问 /sitefromscratch/search1.jsp 能够得到和目标一致的效果。
STEP 2,通过界面所展示的内容,我们能够大致预计出所须要的数据以及其格式,让我们增加少量的代码实现相同的效果:
<%@ page pageEncoding="UTF-8"%>
<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%!
class Result {
String title;
String content;
public Result(String title, String content) {
this.title = title;
this.content = content;
}
}
%>
<%
String keywords = "site from scratch"; List results = new ArrayList();
results.add(new Result("result 1", "something.................."));
results.add(new Result("result 2", "something.................."));
results.add(new Result("result 3", "something.................."));
results.add(new Result("result 4", "something.................."));
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head> <body>
<h1>search it!</h1> <form action="" method="get">
<input type="text" value="<%=keywords %>" name="keywords" />
<input type="submit" value="search!" />
</form> <%
if(!results.isEmpty()) {
%>
<table border="1" bordercolor="grey" >
<%
for(int i = 0; i < results.size(); i++) {
Result result = (Result)results.get(i);
%>
<tr>
<td><%=result.title %></td><td><%=result.content %></td>
</tr>
<%
}
%>
</table>
<%
}
%> </body>
</html>
这里,我们构造了一批伪数据(同一时候创建了一个类),并通过相应的运行逻辑,得到了全然一致的展示效果。
STEP 3。如今,该把提交、查询、结果展示的流程走通了:
<%@ page pageEncoding="UTF-8"%>
<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%!
class Result {
public String title;
public String content;
public Result(String title, String content) {
this.title = title;
this.content = content;
}
} public List search(String keywords) {
List results = new ArrayList();
results.add(new Result("result 1", "something.................."));
results.add(new Result("result 2", "something.................."));
results.add(new Result("result 3", "something.................."));
results.add(new Result("result 4", "something..................")); return results;
}
%>
<%
String keywords = request.getParameter("keywords");
if(keywords == null) keywords = ""; List results = search(keywords);
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head> <body>
<h1>search it!</h1> <form action="" method="get">
<input type="text" value="<%=keywords %>" name="keywords" />
<input type="submit" value="search!" />
</form> <%
if(!results.isEmpty()) {
%>
<table border="1" bordercolor="grey" >
<%
for(int i = 0; i < results.size(); i++) {
Result result = (Result)results.get(i);
%>
<tr>
<td><%=result.title %></td><td><%=result.content %></td>
</tr>
<%
}
%>
</table>
<%
}
%> </body>
</html>
这里,我们构造了一个 List search(String keywords)方法,将业务逻辑和页面展示分离开来。分别置于在jsp文件里分离的区块。
STEP 4,接着。为了保持页面的简洁,我们把定义的类和方法提取出来,用包组织起来:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGVsdGF0YW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
package cn.com.sitefromscrath.entity; public class Result { public String title;
public String content; public Result(String title, String content) {
this.title = title;
this.content = content;
}
}
package cn.com.sitefromscrath.service; import java.util.ArrayList;
import java.util.List; import cn.com.sitefromscrath.entity.Result; public class SearchService { public List search(String keywords) { List results = new ArrayList();
results.add(new Result("result 1", "something.................."));
results.add(new Result("result 2", "something.................."));
results.add(new Result("result 3", "something.................."));
results.add(new Result("result 4", "something..................")); return results;
} }
不出意料。SearchService.java 和 Result.java的代码就是直接从search.jsp中copy过去的。
值得一提的是,我们新增了一个BeanFactory类,作为工厂模式的一个实现,它简单的通过指定的ID所相应的类返回产生的实例。
例如以下所看到的:
package cn.com.sitefromscrath; import cn.com.sitefromscrath.service.SearchService; public class BeanFactory { public static Object getBean(String id) {
if("searchService".equals(id)) {
return new SearchService();
} throw new RuntimeException("cannot find the bean with id :" + id);
} }
尽管它如今看来显得画蛇添足了一些,可是在我之后的展开论述中,它将占有非常重要的位置。
如今。jsp文件的内容看起来简洁多了:
<%@ page pageEncoding="UTF-8"%>
<%@page import="java.util.List"%>
<%@page import="cn.com.sitefromscrath.service.SearchService"%>
<%@page import="cn.com.sitefromscrath.BeanFactory"%>
<%@page import="cn.com.sitefromscrath.entity.Result"%>
<%
String keywords = request.getParameter("keywords");
if(keywords == null) keywords = ""; SearchService searchService = (SearchService)BeanFactory.getBean("searchService");
List results = searchService.search(keywords);
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head> <body>
<h1>search it!</h1> <form action="" method="get">
<input type="text" value="<%=keywords %>" name="keywords" />
<input type="submit" value="search!" />
</form> <%
if(!results.isEmpty()) {
%>
<table border="1" bordercolor="grey" >
<%
for(int i = 0; i < results.size(); i++) {
Result result = (Result)results.get(i);
%>
<tr>
<td><%=result.title %></td><td><%=result.content %></td>
</tr>
<%
}
%>
</table>
<%
}
%> </body>
</html>
STEP 5,听说MVC是个非常高科技的东西,我们也来实现一下:
新增一个servlet,作为 控制层 Controller
package cn.com.sitefromscrath.web; import java.io.IOException;
import java.util.List; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import cn.com.sitefromscrath.BeanFactory;
import cn.com.sitefromscrath.service.SearchService; public class SearchServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { String keywords = request.getParameter("keywords");
if(keywords == null) keywords = ""; SearchService searchService = (SearchService)BeanFactory.getBean("searchService");
List results = searchService.search(keywords); request.setAttribute("keywords", keywords);
request.setAttribute("results", results); request.getRequestDispatcher("/search5.jsp").forward(request, response);
} }
新增一个jsp文件。search5.jsp,作为视图层 Viewer。
<%@ page pageEncoding="UTF-8"%>
<%@page import="java.util.List"%>
<%@page import="cn.com.sitefromscrath.entity.Result"%>
<%
String keywords = (String)request.getAttribute("keywords");
List results = (List)request.getAttribute("results");
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head> <body>
<h1>search it!</h1> <form action="" method="get">
<input type="text" value="<%=keywords %>" name="keywords" />
<input type="submit" value="search!" />
</form> <%
if(!results.isEmpty()) {
%>
<table border="1" bordercolor="grey" >
<%
for(int i = 0; i < results.size(); i++) {
Result result = (Result)results.get(i);
%>
<tr>
<td><%=result.title %></td><td><%=result.content %></td>
</tr>
<%
}
%>
</table>
<%
}
%> </body>
</html>
web.xml中配置:
<? xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>SearchServlet</servlet-name>
<servlet-class>cn.com.sitefromscrath.web.SearchServlet</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>SearchServlet</servlet-name>
<url-pattern>/search</url-pattern>
</servlet-mapping> <welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list> </web-app>
如今,让我们再来run一次,http://localhost:8080/sitefromscratch/search
binggo。效果跟目标无差!
——————————————————————————————————————————————————————————
嗯,到这里。我们究竟达到了什么目的?数据还是假的啊,有这个必要吗?有这个必要吗?
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGVsdGF0YW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
看看,葛大爷已经被拍了一脸血了。我希望您还没到这地步。
到了这一步。我们事实上完毕了跟前端页面制作人员的握手协议:
您写js的也好,html5的也好,随便整,我返回的数据格式和内容您也看见了,就这样。格式不会变,内容也不会出错。
数据怎么嵌,那是您的事儿,俺就不侍奉了。
关于”内容不会出错“这句,补充一点儿,这是指的前端页面人员(或许是你自己兼任)无需启动一大堆复杂的应用程序,比方mysql、memcache,就能调试自己的html或者js代码。同一时候,也避免了其它异常(数据库down了。数据表毁坏了,网络断了,memcache连接不上了等等等等)对前端开发的干扰。
特别是debug阶段,假设你不能确保哪些是正确的。你就无法找到错误的。
非常多程序猿在debug排查某个问题的时候。最常犯的错误就是迷失在一大堆的模块中间,找不到出路,造成这样的情况的根本原因就在于:在当事人看来,每一个模块都是可疑的,不确定的。要么猜要么一个个查,精力和时间就此白白浪费。
而对于后端开发者来说,如今面临的就仅仅剩一个任务:让以下的类方法返回真实的业务结果吧。
package cn.com.sitefromscrath.service; import java.util.ArrayList;
import java.util.List; import cn.com.sitefromscrath.entity.Result; public class SearchService { public List search(String keywords) { List results = new ArrayList();
results.add(new Result("result 1", "something.................."));
results.add(new Result("result 2", "something.................."));
results.add(new Result("result 3", "something.................."));
results.add(new Result("result 4", "something..................")); return results;
} }
我们将在下一章讨论这个问题。
WEB开发那些事儿 |
||
第一部分:从需求出发 |
||
一 |
这里从一个静态html页面说起。逐步抽离出展示层面和数据层面的东西。 |
|
二 |
这里主要说的是工厂方法。 当然,工厂不是目的,而是结果,需求才是源起。 |
|
三 |
这里開始扯到了spring和《儿歌三百首》 |
|
四 |
对spring的吐槽 |
|
五 |
让我们充当一次麦克斯韦妖。探測和控制单个模块/方法的工作 |
|
六 |
MVC模式的得失。开发的时候。别由于迷失才过程里尔忘记了我们的目的。 |
|
第二部分:拿起笔来做刀枪 |
||
序 |
拿起笔来做刀枪,开发路上当闯将 |
|
一 |
标题说明了一切 |
|
二 |
标题说明了一切 |
|
三 |
标题说明了一切,这里的 jsp 不是 java server pages,而是java sign pages :) |
|
四 |
标题说明了一切 |
|
五 |
标题说明了一切,lucene的原理仅仅须要一句话说清楚,这个就是我喜欢他的原因 |
|
六 |
事实上我在意的是HQL怎样映射到多种sql查询语言上 |
|
七 |
终于的成品 |
版权声明:本文博客原创文章,博客,未经同意,不得转载。
发展,需求驱动 · 一间 所见即所得的更多相关文章
- 解析图书 XML
Java代码: package com.thinkgem.jeesite.test; import org.dom4j.Attribute; import org.dom4j.Document; im ...
- 基于低代码平台(Low Code Platform)开发中小企业信息化项目
前言:中小企业信息化需求强烈,对于开发中小企业信息化项目的软件工作和程序员来说,如何根据中小企业的特点,快速理解其信息化项目的需求并及时交付项目,是一个值得关注和研讨的话题. 最近几年来,随着全球经济 ...
- IT项目管理十大要素
1.项目需求PgMp.mypm.net 当项目混乱和不可控的时候,往往是源头出了问题,解决源头才能治本.项目管理者联盟文章 软件项目中的范围管理重点就是项目需求,需求包括原始需求,用户需求,产品需求和 ...
- CIO在数字化转型中如何正确定位?
在数字化转型的大潮下,CIO和传统企业应如何抓住数字生态系统中的机遇?CIO该如何面对领导力.资金.技术和人才的挑战? Gartner研究总监陈勇表示:IT部门在企业中应转变成为一个引领创新的部门,C ...
- 054 Python程序设计思维
目录 一.单元开篇 二.计算思维与程序设计 2.1 计算思维 2.1.1 第3种人类思维特征 2.1.2 抽象和自动化 2.1.3 计数求和:计算1-100的计数和 2.1.4 圆周率的计算 2.1. ...
- HANA到MySQL数据同步方法!
随着各行各业信息化建设的不断发展,异构数据库间的互通.汇聚,挖掘,分析逐渐被提上日程, TreeSoft数据库管理系统,实现了异构数据库的维护.监控.可视化.自动交换同步.目前支持MySQL,Orac ...
- 阿里云场景化阿里云企业数字化转型售前方法PSA
阿里云场景化阿里云企业数字化转型售前方法PSA 目录 01 课程收获 理解企业数字化转型的概念.内涵.本质 了解企业数字化转型的要点.目标和切入点 掌握数字化转型项目售前阶段实践方法 场景化方案 阿里 ...
- 初学者应该怎么学习前端?web前端的发展路线大剖析!
写在最前: 优秀的Web前端开发工程师要在知识体系上既要有广度和深度!应该具备快速学习能力. 前端开发工程师不仅要掌握基本的Web前端开发技术,网站性能优化.SEO和服务器端的基础知识,而且要学会运用 ...
- 星浩资本快速发展引擎:IT就是生产力
星浩资本成立于2010年,是一家涵盖私募基金.开发管理.商业与现代服务业三大业务范围的综合性管理公司,专注于投资中国首创.高成长性.高回报率的创新型城市综合体. 年轻的星浩资本在商业投资上有其独到的商 ...
随机推荐
- poj 1011 Sticks ,剪枝神题
木棒 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 118943 Accepted: 27429 Description 乔治拿 ...
- Wix打包系列(七) 添加系统必备组件的安装程序
原文:Wix打包系列(七) 添加系统必备组件的安装程序 我们知道在vs的打包工程中添加系统必备组件是一件很容易的事情,那么在wix中如何检测系统必备组件并在安装过程中安装这些组件.这里以.Net Fr ...
- hdu4283(区间dp)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4283 题意:有一个队列,每个人有一个愤怒值D,如果他是第K个上场,不开心指数就为(K-1)*D.但是边 ...
- Java程序猿笔试面试之String1
1.怎样实现字符串的反转比如:"how are you"--->"you are how" public class InverseString { pu ...
- Bootstrap之表格
基本实例 为随意<table>标签加入.table类能够为其赋予主要的样式-少量的内补(padding)和水平方向的分隔线. <table class="table&quo ...
- VC6.0入门使用
软件下载地址 http://pan.baidu.com/s/1qWuqFAO 新建win console 32 project,然后新建header文件.最后新建source cpp文件.如图所看到的
- VMware虚拟机上网络连接(network type)的三种模式--bridged、host-only、NAT
VMware虚拟机上网络连接(network type)的三种模式--bridged.host-only.NAT VMWare提供了三种工作模式,它们是bridged(桥接模式).NAT(网络地址转换 ...
- windows phone 7 客户端和web的交互(WebBrowser的使用)
原文:windows phone 7 客户端和web的交互(WebBrowser的使用) 前几天看到淘宝的Android客户端,有种促销的功能,当点击促销的时候连接的淘宝促销wap页面,然后点击商品后 ...
- 打开或导入项目,从脱机 Outlook 数据文件 (.ost)
打开或导入项目,从脱机 Outlook 数据文件 (.ost) Microsoft Outlook 2010 doesn\rquote t 支持手动打开或导入项目,从一个 脱机 Outlook 数据文 ...
- java连接数据库——JDBC连接数据库
DBUtil.java // 数据库操作文件 package com.bjpowernode.jdbc.util; import java.io.File; import java.io.File ...