發展,需求驅動 · 一間 所見即所得 (WYSIWYG)

來源:互聯網
上載者:User

標籤:

從需求不是一句空話。同樣是在發展過程中真正的。

需求驅動,與極限編程的一些想法和測試驅動開發基本重合。

鑒於該網站的發展是一個比較流行的方向,我會從網站開始,闡述自己的“需求驅動的發展“認識,並擴充到更廣泛的領域。


首先,我們如果一個需求:

我們須要實現一個類似google的網站,使用者通過web瀏覽器訪問,在首頁輸入框中查詢。返回搜尋的結果。

效果例如以所看到的:


STEP 0,通過eclipse建立一個web項目:sitefromscratch。檔案結構所看到的:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZGVsdGF0YW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" >

在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" >


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" >

看看,葛大爺已經被拍了一臉血了。我希望您還沒到這地步。


到了這一步。我們事實上完畢了跟前端頁面製作人員的握手協議:

您寫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開發那些事兒

第一部分:從需求出發

一

所見即所得 (WYSIWYG)

這裡從一個靜態html頁面說起。逐步抽離出展示層面和資料層面的東西。

二

造飛機的工廠

這裡主要說的是Factory 方法。

當然,工廠不是目的,而是結果,需求才是源起。

三

春天在哪裡

這裡開始扯到了spring和《兒歌三百首》

四

春天在這裡

對spring的吐槽

五

麥克斯韋妖

讓我們充當一次麥克斯韋妖。探測和控制單個模組/方法的工作

六

扒皮MVC

MVC模式的得失。開發的時候。別由於迷失才過程裡爾忘記了我們的目的。

第二部分:拿起筆來做刀槍

序

序言

拿起筆來做刀槍,開發路上當闖將

一

再造一個dom4j

標題說明了一切

二

再造一個spring

標題說明了一切

三

再造一個jsp

標題說明了一切,這裡的 jsp 不是 java server pages,而是java sign pages :)

四

再造一個struts

標題說明了一切

五

再造一個lucene

標題說明了一切,lucene的原理僅僅須要一句話說清楚,這個就是我喜歡他的原因

六

再造一個hibernate

事實上我在意的是HQL怎樣映射到多種sql查詢語言上

七

Final Fantasy

終於的成品


著作權聲明:本文部落格原創文章,部落格,未經同意,不得轉載。

發展,需求驅動 &#183; 一間 所見即所得 (WYSIWYG)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.