丁香五月天婷婷国产|91麻豆精品|另类婷婷五月天网站|日韩无码视频中出|无码任你躁久久久|狠狠的搞激情99|草在线观看视频免费|精品999ww网站|久久无码综合一区|一区二区三区四区αα

您好,歡迎來到中國企業(yè)庫   [請登陸]  [免費注冊]
小程序  
APP  
微信公眾號  
手機版  
 [ 免責聲明 ]     [ 舉報 ]
客服電話:13631151688
企業(yè)庫首頁>資訊
行業(yè)
超級獵聘人才網(wǎng) 廣告

寫給java web一年左右工作經(jīng)驗的人

作者:成都佳薇科技有限公司 來源:cici1949 發(fā)布時間:2015-09-01 瀏覽:321

我把我這些年在java學習中學到的東西,按照項目開發(fā)中可能遇見的場景,進行了一次梳理。

這個故事是我{zh1}決定加上來的,我非常喜歡這個故事,軟件工程中有一個被戲稱為Cargo Cult編程法的編程風格,而下面這個故事講述了此編程法的來源:
早在40年代,據(jù)說,美軍曾駐扎在一個偏遠的島嶼。島上的土著居民在此以前從未見過的現(xiàn)代文明,所以,他們對聯(lián)軍和他們帶來的東西非常驚奇。他們發(fā)現(xiàn)聯(lián)軍修建了機場跑道和控制塔,帶著耳機的士兵對天呼叫,然后滿載著大量貨物的大鐵鳥便從天而降。當鐵鳥降落后,貨物便分發(fā)給所有島上的人們,為人們帶來繁榮。
終于,有{yt},bd離開了,大鐵鳥也不再回來了。為了再次得到貨物,島上的土著居民用竹子建造了自己的跑道,控制塔,讓他們的頭領登上平臺,并讓他戴上用椰子做的耳機。但無論他們?nèi)绾闻L試,大鐵鳥再也沒有回來。
幾十年后,研究人員發(fā)現(xiàn)了該島。島上的土著居民仍舊保留著這一宗教儀式。他們把島上居民的這一奇怪的宗教儀式命名為“Cargo Cult”

@考慮這樣一個應用場景:我們的項目功能日漸強大,代碼卻日漸臃腫,我們?nèi)绾螌⒋a變得有條理些?
無論我們是學習還是工作,我們的前輩總是會告訴我們,我們需要把java項目進行架構(gòu)上的分層,界面層(UI)業(yè)務邏輯層(BLL) 數(shù)據(jù)訪問層(DAL),就像Cargo Cult中的土著居民一樣,雖然我們并不知道為什么高手們要那樣做,但是我們相信這么做可以讓程序工作起來,后面我會講到為什么會有所謂的經(jīng)典的三層架構(gòu),現(xiàn)在我們已經(jīng)做完的事是,按照三層架構(gòu)將項目搭建并運行起來了!

我們一般會想到MVC,很多http://.都有說到,可惜很多時候我們理解的MVC是錯誤的。。。甚至我曾經(jīng)天真的以為,MVC正好對應著DAL,UI,BLL。。。實際上,這兩者并沒有顯式的關系,前者屬于設計模式,而后者屬于架構(gòu)設計的范疇,如果一定要扯到一起的話,關系可能會是這樣的:

 
http://.

實際上,Controller是很薄的一層,它僅僅負責接收參數(shù),封裝參數(shù),調(diào)用不同的service。所以我們可以考慮先從它入手,簡化代碼。
我們現(xiàn)有的controller做法是,不同的業(yè)務調(diào)用不同的servlet,通過參數(shù)的不同,調(diào)用不同的方法,比如,有下面一個form

http://.

1

2

3

4

<formaction=”UserServlet?command=login”>

<inputname=”name”/>

<inputname=”password”/>

</form>

如果我們在這個表單中輸入用戶名密碼,最終后臺會將這個請求提交到UserServlet中,然后根據(jù)command=login,調(diào)用UserServlet中的login方法。在login方法中,會有這樣的一段代碼:

http://.

1

2

3

4

5

6

7

8

Stringname=request.getAttribute(“name”);

Stringpassword=request.getAttribute(“password”);

Booleanresult=userService.hasUser(name,password);

if(result){

....

}else{

....

}

我們可以發(fā)現(xiàn),基本上這個servlet中,所有的方法幾乎都有著從request中獲取參數(shù)的這么一個過程,而且同一個servlet中,需要獲取的參數(shù)大部分都是重疊的(比如UserServlet中,幾乎所有的方法都需要獲取name和password的值,才能進行近一步操作),既然每一個方法都有這么一個需求,為什么不考慮將這一過程抽象出來呢?
首先,我們可以設計一個叫AaronDispatcher的類,它負責截取了所有的對項目的訪問的http請求。
比如,我們上面的請求叫UserServlet?command=login,同時傳遞三個參數(shù)name和password(以及上面的command) 。AaronDispatcher巨牛叉,它直接把這個請求截取了,并進行分析,首先它的名字叫UserServlet,調(diào)用的方法叫l(wèi)ogin。為了不引發(fā)歧義,我們更改前臺的請求地址,改為發(fā)送到UserAction?command=login。
然后我們可以重新設計UserServlet,創(chuàng)建全新的UserAction。(現(xiàn)已加入豪華午餐)

http://.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

publicUserAction{

Stringname;

Stringpassword;

Stringnewpassword;//updatePassword這個方法需要

Stringoldpassword;

......//所有的UserAction從前端獲取的參數(shù)

publiclogin(){

...

}

publiclogout(){

...

}

publicupdatePassword(){

...

}

......//所有UserAction需要提供的方法

}//UserAction結(jié)束

(眼疾手快的人也許可以注意到一點:這個類不再需要接受HttpServletRequest及HttpServletResponse作為參數(shù)了)
每當我們有一個發(fā)送到UserAction的請求,AaronDispatcher就幫我們new一個新的UserAction實例,同時將請求中的參數(shù)賦給UserServlet中的屬性。具體的底層做法,類似于下面這樣:(實際上會復雜很多,不會直接new對象,而是使用反射來創(chuàng)建對象并賦值屬性)

http://.

1

2

3

4

5

6

UserActionuserAction=newUserAction();

userAction.setName(request.getAttrbute(“name”));

userAction.setPassword(request.getAttrbute(“password”));

userAction.setNewpassword(request.getAttrbute(“newpassword”));

userAction.setOldpassword(request.getAttrbute(“oldpassword”));

......

如果我們需要http://.登陸功能,直接調(diào)用userAction.login()就可以了(至于name和password,直接可以在方法內(nèi)部獲取當前對象屬性)。所有的方法中,從request中獲取參數(shù)并進行封裝的這么一個過程,全部都被巨牛叉的AaronDispatcher做了,是不是減少了很多重復的代碼量?!
可能會有疑慮,所有的請求,無論什么方法,都進行一次屬性全賦值,如果前臺沒有傳入這個屬性,不就為空了嘛?但是要知道,如果我們調(diào)用login這個功能,newpassword和oldpassword固然會因為前臺沒有相應的屬性值傳入而設為null,但是,但是,在login方法中,我們根本就不會用到這兩個參數(shù)??!所以即使為空也不會有錯的!
甚至我們可以做的再牛叉一點,AaronDispatcher會去讀取一段配置文件,配置文件中指定了什么樣的請求調(diào)用什么養(yǎng)的類以及相應的方法,這樣我們就可以徹底解耦最前方的Controller了!
但是AaronDispatcher是怎么做到無論什么類,當中有什么屬性,我們都不需要事先知道,我們都可以接收前端參數(shù),給他們的屬性賦值呢?(答案是通過反射)
現(xiàn)在,我們已經(jīng)成功的重新發(fā)明輪子了!
因為以上這個偉大的想法已經(jīng)有被別人搶在前面實現(xiàn)了,就是zm的Struts2,毋庸置疑,Struts2的核心功能就是這么簡單。
在Struts2中,每一個處理類被稱之為Action,而Struts2也正是通過xml配置文件,實現(xiàn)了無需要修改代碼,通過修改配置文件,就可以修改Controller。
Struts2發(fā)展到今天已然是一個功能齊全的龐然大物了。
正如一開始所說,MVC框架只不過幫助我們封裝了請求參數(shù),分發(fā)了請求而已。Controller是非常薄的一層,而我們的業(yè)務邏輯都是由BLL層提供的Service對象實現(xiàn)。
首先講述一下為什么會有所謂BLL(Business Logic Layer)和DAL(Dataaccess Layer)了。在一個項目中,無論是查詢用戶的用戶名,還是查詢庫存數(shù)量,這些數(shù)據(jù)終歸是要保存到數(shù)據(jù)庫的,而這些對數(shù)據(jù)庫的操作將會mb的頻繁,如果我們不將這些對數(shù)據(jù)庫表的操作獨立出來,如果在多個方法中存在著對一個用戶記錄的查詢,我們不得不把這段代碼copy、paste無數(shù)次,既然這樣,我們?yōu)槭裁床幌裆厦婺菢?,將這種可能會多次遇到操作抽象出來呢?于是就有了所謂的DAL了,這樣,無論在什么地方,需要用到數(shù)據(jù)庫查詢相關的工作的時候,僅僅需要這么做:

http://.

1

2

Useruser=userDaoImp.getUserById(userId);

......

這么做有一個好處:減少了因為持久化方案的更換而導致的代碼修改帶來的工作。
持久化是一個非常gd大氣的專業(yè)術語,說的更專業(yè)一點,就是將內(nèi)存中的數(shù)據(jù)保存到硬盤中。在我們的項目中,用戶進行了注冊,我們需要將用戶注冊的用戶名密碼保存起來,以便下次用戶登陸的時候我們能夠知道,這個用戶名的用戶是合法注冊過的。
通常持久化的方案就是將數(shù)據(jù)保存到數(shù)據(jù)庫中,但是我相信如果我不愿意使用數(shù)據(jù)庫,而直接將用戶名密碼明文保存到文本文件中,也沒有人會從技術上反對吧(實際上這種事情在中國互聯(lián)網(wǎng)的發(fā)展歷史中還真發(fā)生過。。。),如果我真的選擇這么做,我所需要做的工作就是僅僅修改DAL中的實現(xiàn),將對數(shù)據(jù)庫的操作改為對本地文件的操作,而無須修改調(diào)用持久化方法的方法。
業(yè)務層負責業(yè)務的處理(接收上層傳過來的信息進行處理),當處理完之后,將處理的結(jié)果利用DAL的對象進行“保存到硬盤”。而DAL具體是怎么實現(xiàn)的,wq不會影響到已實現(xiàn)的業(yè)務。
很明顯的,為了做到上面這一點,DAL中的方法要盡量的“單純”,不包含任何的業(yè)務上的邏輯,僅僅是將內(nèi)存中的數(shù)據(jù)(一般就是某個對象)保存到硬盤的“實現(xiàn)”,以及從硬盤讀取的數(shù)據(jù)提取到內(nèi)存的“實現(xiàn)”。
已經(jīng)很明顯了,三層架構(gòu)不是從來都有的,只不過是在無數(shù)次痛苦的經(jīng)歷過后先烈們總結(jié)出來的一套證明可以在某一方面減少因變動而帶來的額外工作量。說它經(jīng)典,也只不過是因為它實現(xiàn)了展示、業(yè)務、持久化這三個必不可少卻又相對對立的需求的切割(不過確實有的項目中,展示不是必選的)。
所以基本上所有的復雜架構(gòu)也只不過是在此基礎上的進一步分割,曾經(jīng)做過一個巨復雜SaaS項目,為了減少某些不定因素的變動而帶來的代碼上的改動,架構(gòu)師將BLL分成了兩層,在原有的BLL之上又增加了一層core business layer。這樣MVC框架只需要調(diào)用core business的業(yè)務而無須自己在重復組裝比較底層的業(yè)務邏輯了。
如果有更復雜些的項目的話,就需要通過分割子項目及更復雜的層級關系來解決了。
這個時候我們或許應該講述BLL了,不過在此之前,我們可以再多想一步,能不能修改DAL中的東西,讓我們使用起來更簡單?
一般來說,數(shù)據(jù)庫中的表對應著java中的類,表中的一行記錄對應著一個entity對象,表中的字段對應著對象中的屬性,我以前一直覺得很神奇,這就是傳說中的ORM。這當中還有很多更復雜的東西,比如多表級聯(lián)的結(jié)果映射為對象,在這里我們先忽略這些復雜的情況。
有了上面的知識,我們可以發(fā)現(xiàn), 如果我們選擇關系型數(shù)據(jù)庫作為持久化方案,我們的DAL其實也很“單純”,他們所做的也不過是將對象屬性通過sql存儲到數(shù)據(jù)庫、將通過sql獲取的數(shù)據(jù)封裝為對象。
同樣的我們可以寫一個巨牛叉框架(好吧,這次不是寫一個巨牛叉的類了),它會自動根據(jù)我們entity的名字,去數(shù)據(jù)庫尋找相應的表,當我們調(diào)用insert,delete,update,select等方法的時候,它會自動幫助我們根據(jù)要求及參數(shù)拼接sql,然后去數(shù)據(jù)庫查詢/修改記錄,如果是查詢,則把查詢出來的記錄集封裝成對象,保存在list中。這樣,我們就可以在DAL中簡單的定義一些entity就可以了。


鄭重聲明:資訊 【寫給java web一年左右工作經(jīng)驗的人】由 成都佳薇科技有限公司 發(fā)布,版權歸原作者及其所在單位,其原創(chuàng)性以及文中陳述文字和內(nèi)容未經(jīng)(企業(yè)庫www.5ix2s.cn)證實,請讀者僅作參考,并請自行核實相關內(nèi)容。若本文有侵犯到您的版權, 請你提供相關證明及申請并與我們聯(lián)系(qiyeku # qq.com)或【在線投訴】,我們審核后將會盡快處理。
會員咨詢QQ群:902340051 入群驗證:企業(yè)庫會員咨詢.
免費注冊只需30秒,立刻尊享
免費開通旗艦型網(wǎng)絡商鋪
免費發(fā)布無限量供求信息
每天查看30萬求購信息