发展,需求驱动 · 一间 所见即所得

发展,需求驱动 · 一间 所见即所得

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

从需求不是一句空话。同样是在发展过程中真正的。

需求驱动,与极限编程的一些想法和测试驱动开发基本重合。

鉴于该网站的发展是一个比较流行的方向,我会从网站开始,阐述自己的“需求驱动的发展“认识,并扩展到更广泛的领域。

首先,我们如果一个需求:

我们须要实现一个类似google的站点,用户通过web浏览器訪问,在首页输入框中查询。返回搜索的结果。

效果例如以下图所看到的:

发展,需求驱动 · 一间 所见即所得

STEP 0,通过eclipse创建一个web项目:sitefromscratch。文件结构如图所看到的:

发展,需求驱动 · 一间 所见即所得

在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,接着。为了保持页面的简洁,我们把定义的类和方法提取出来,用包组织起来:

发展,需求驱动 · 一间 所见即所得

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。效果跟目标无差!

——————————————————————————————————————————————————————————

嗯,到这里。我们究竟达到了什么目的?数据还是假的啊,有这个必要吗?有这个必要吗?

发展,需求驱动 · 一间 所见即所得

看看,葛大爷已经被拍了一脸血了。我希望您还没到这地步。

到了这一步。我们事实上完毕了跟前端页面制作人员的握手协议:

您写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

MVC模式的得失。开发的时候。别由于迷失才过程里尔忘记了我们的目的。

第二部分:拿起笔来做刀枪

序言

拿起笔来做刀枪,开发路上当闯将

再造一个dom4j

标题说明了一切

再造一个spring

标题说明了一切

再造一个jsp

标题说明了一切,这里的 jsp 不是 java server pages,而是java sign pages :)

再造一个struts

标题说明了一切

再造一个lucene

标题说明了一切,lucene的原理仅仅须要一句话说清楚,这个就是我喜欢他的原因

再造一个hibernate

事实上我在意的是HQL怎样映射到多种sql查询语言上

Final Fantasy

终于的成品

版权声明:本文博客原创文章,博客,未经同意,不得转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/117589.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • php curl_init函数用法

    php curl_init函数用法使用PHP的cURL库可以简单和有效地去抓网页。你只需要运行一个脚本,然后分析一下你所抓取的网页,然后就可以以程序的方式得到你想要的数据了。无论是你想从从一个链接上取部分数据,或是取一个XML文件并把其导入数据库,那怕就是简单的获取网页内容,cURL是一个功能强大的PHP库。PHP中的CURL函数库(ClientURLLibraryFunction)curl_close—关

    2022年7月12日
    12
  • eclipse怎么导入一个Java项目(莫要错过,最详细教程!)

    eclipse怎么导入一个Java项目(莫要错过,最详细教程!)对于eclipse软件,常规的打开文件方法是无法打开一个项目的,那么怎样导入一个java项目呢?方法如下第一步在电脑打开eclipse软件,点击file->Import,如下图所示:第二步选择General->ExistingProjectsintoworkspace,点击next,如下图所示:第三步点击选择要导入的项目路径,选好,点击finish,如下图所示:到此为止,已经导入成功了如果对你产生了帮助,那么请给博主一个小小的赞哦。…

    2022年7月7日
    30
  • JS刷新当前页面的五种方式

    JS刷新当前页面的五种方式https://www.jb51.net/article/44764.htm

    2022年7月27日
    4
  • linux 7z压缩、解压命令「建议收藏」

    linux 7z压缩、解压命令「建议收藏」原文地址:https://blog.csdn.net/jk110333/article/details/7829879支持7Z,ZIP,Zip64,CAB,RAR,ARJ,GZIP,BZIP2,TAR,CPIO,RPM,ISO,DEB压缩文件格式安装:sudoapt-getinstall p7zip-full# 7zayajiu.7zyajiu.jpgyajiu.png…

    2022年5月13日
    229
  • win10黑群晖安装教程_黑群晖7.0安装教程

    win10黑群晖安装教程_黑群晖7.0安装教程使用芯片无忧工具,查看U盘的和。使用,格式化U盘。使用镜像写入工具,把引导写入U盘。修改文件,可以使用工具把文件复制到桌面,通过修改好之后,拖进这个界面中。或者在电脑中,查看U盘,打开U盘中的文件直接修改。具体修改内容如下:,因为我的主板上有4个sata口,然后PCIE扩展了6个SATA口,所以这里写了46,分别对应主板的SATA数目和PCIE的SATA数目。,因为主板的4个SATA口分别为00、01、02、03,所以PCIE的SATA从04开始。也就是说,前面两个00代表主板上的SATA控制从00开始计数

    2025年6月14日
    0
  • JavaScript中window.open()和Window Location href的区别「建议收藏」

    JavaScript中window.open()和Window Location href的区别「建议收藏」目录1:window.location.href的用法:2:window.open()的用法3:window.open和window.location.href的区别1:区别2.window.open不一定是打开一个新窗口!!!!!!!!3:关于重新定位4.:在框架内指定页面打开连接5:是否打开其他网站地址6:window.open()经过设置后的弹…

    2022年7月12日
    19

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号