dao模式和前端控制器结合使用_前端技术及开发模式的演进,带你了解前端技术的前世今生...
先聲明,本篇不會講帶有年代性的前端發展史,不講故事,想了解的讀者可以去查閱一些其他的資料和文章,本篇僅僅從技術發展角度結合案例分析,說明前端技術的發展和開發模式的演進變化。本篇內容重點說明PC端技術,移動端、桌面端本篇不涉及,防止讀者看到后面有疑惑,這里強調一下。
這里先講一個需求,有一個系統需要實現一個模塊,用戶管理,模塊的功能很簡單,就是查詢、刪除。基于這個需求,南風哥會使用幾代不同的前端技術分別予以實現,讓讀者感受其中的變化和奧秘。界面大概是這個樣子。
非常老土,非常簡單,這都不是重點,重點是能說明問題就行。
第一代:單文件模式
何為單文件模式,解釋一下就是一個模塊所有的代碼都集中在一個文件中,實現上面說的需求,目錄大概是這個樣子的。
然后看「user.html」具體里面的內容。
用戶管理用戶添加
用戶姓名:查詢 id 姓名 性別 年齡 聯系電話 創建時間 操作 1 張三 男 22 123456789 2018-08-08 刪除 2 李四 女 18 987654321 2018-07-18 刪除我們會發現,所有的樣式聲明,js代碼以及html代碼都會集中在一個文件中。這樣一個功能如果較為復雜,頁面代碼看起來會非常復雜,久而久之就會變得不易維護。
當然有一些優化的方式。就是目錄劃分更友好一些,剝離css和js腳本,采用外部引入的方式,這種方式也是后來采用的比較多的方式,像下面這樣,看起來就清爽多了。
用戶管理用戶添加
用戶姓名:查詢 id 姓名 性別 年齡 聯系電話 創建時間 操作 1 張三 男 22 123456789 2018-08-08 刪除 2 李四 女 18 987654321 2018-07-18 刪除以上兩種形式,本質上沒有什么區別,所以就放在一起說明,以上方式的優點就是簡單粗暴,代碼開發的速度較高。
與后端的交互都是后端建立一個Controller或Servlet 這么一個控制器,請求到達控制器,處理完邏輯,然后控制器中跳轉到一個頁面,頁面進行數據渲染展示。每次交互過程目標跳轉頁面的內容都需要全部刷新加載,即使多次交互跳轉的是同一個頁面。
這種有什么問題嗎?我們來看一下,在用戶管理中的用戶列表頁我們有個查詢功能,我們輸入一個姓名,點擊查詢,如果采用上面的方式,想想看,點一下查詢,到控制器,后端執行完SQL拿到數據后,又會跳轉到用戶列表頁,我點5次查詢,整個列表頁就會加載5次,而且整個頁面只有用戶表格這個部分是變化的,其他部分是沒有變化的,這樣資源(背景圖、jquery庫、css)每次就是重復加載,帶來的問題就是一、體驗不好,二、資源重復加載,給web服務器帶來一定的請求壓力。
這里補充多說一點內容,就是jsp這個東西,雖然現在用的不多,但還是說一下,之前南風哥面試問過很多面試者,前端都會什么技術,面試者張口就來,jsp .... 什么什么,這里南風哥想說,jsp不屬于前端技術,為什么 ?
因為jsp本身執行前是需要編譯的,編程成class文件,是在服務端執行的,而真正的前端技術一定是在瀏覽器或相關前端技術執行引擎上(類Chrome V8)解釋執行的。像jsp里寫的css、html、js這些東西屬于前端技術的范疇,這些都是由瀏覽器解釋執行的,很多人被jsp這種表象迷惑了,看到jsp里面寫的都是頁面展現相關的代碼,認為jsp就是前端技術。
回到上面的問題,我們再來看如何解決上面的問題,這就是第二代技術。
第一代代表技術:html、css、javascript、jquery
第二代:SPA
單頁Web應用(single page web application,SPA),簡稱SPA,由于ajax技術的興起,使得局部加載變得流行,單頁應用頁得到了廣大開發者和用戶的青睞。
簡單理解單頁應用,就是整個應用加載都在一個頁面當中,做的就是局部替換,比如點擊一個菜單,系統整個頭部,底部,菜單部分都不變化,只變化中間區域的模塊內容。
再比如上面說到的查詢需求,點擊查詢后,用戶列表整體內容不變,通過ajax請求,數據回來后,通過js僅僅修改表格部分的數據內容。
這樣就解決了上面說的一、體驗的問題,二、資源重復加載的問題。
大部分情況下,我們只需要在整體頁面中引入需要的所有資源,模塊中就不需要在引入資源,只處理模塊自身的內容和業務即可。
這種方式與后端的交互都是就是建立一個Controller或Servlet 這么一個控制器,請求到達控制器,處理完邏輯,然后返回局部頁面片段或者json數據,頁面進行渲染展示。每次交互過程只刷新局部,整體頁面不做刷新。
這里的數據渲染,一種是通過jquery或js的方式,字符串拼接,然后設置到對應的dom中,像這樣。
頁面Dom
Ajax加載渲染
function search(){ var name = $("#name").val(); // 調用控制器搜索方法,返回json數據 $.get('/userList?name=' + name,{},function(data){ var userList = data.userList; var row = ''; row += ''; row += ' id'; row += ' 姓名'; row += ' 性別'; row += ' 年齡'; row += ' 聯系電話'; row += ' 創建時間'; row += ' 操作 '; row += ' '; for(var i = 0 ; i < userList.length; i++){ var user = userList[i]; row += ''; row += ' ' + user.id + ''; row += ' ' + user.name +''; row += ' ' + user.sex + ''; row += ' ' + user.age +' ''; row += ' ' + user.phone + ''; row += ' ' + user.createDate + ''; row += ' 刪除'; row += ''; } $("#userList").html(row); },'json');}另一種方式模板引擎
使用
function search(){ var name = $("#name").val(); // 調用控制器搜索方法,返回json數據 $.get('/userList?name=' + name,{},function(data){ var userList = data.userList; var html = template('userListTpl', userList); document.getElementById('userList').innerHTML = html; },'json');}復雜頁面建議使用模板引擎的方式,代碼結構更清晰,更容易維護。
這種方式的優點,顯而易見可以解決第一代技術的問題,那它有問題嗎 ? 顯然有,一、破壞瀏覽器的后退、前進功能(異步加載,地址欄不發生變化,所以是無法后退前進),當然有一些解決辦法,下面再說 ,二、SEO不友好。
所以比較常見的做法是,后端管理系統一般會整體采用SPA方式,包括現在的很多系統也是,有強SEO需求的仍然會采用上面第一代方式,然后結合一點點ajax的內容,這便是第二代前端的開發模式。
局部加載的實現方式:
1、ajax 局部請求加載
2、前端hash路由,也是現在的主流方式,這種方式可以解決瀏覽器的前進、后退問題,通過地址欄hash值的變化,但歷史頁面狀態無法保持,回退的頁面數據仍需要重新加載、初始化,但隨著前端數據持久化的逐步流行,回退歷史頁面狀態的保存也漸漸不是問題。
3、iframe、frameset 也可以實現,但是不建議。
第二代代表技術:ajax、artTemplate
第三代:模塊化
隨著系統功能越來越多,代碼文件也越來越多,相互之間的依賴調用關系變得異常復雜。這時候兩個問題變得十分突出,一是js中的命名沖突問題,二是資源的加載問題。
先看js的命名問題,看一個簡單的js文件
function deleteUser(e,id){ // 調用控制器刪除方法 // 后端邏輯是,控制器調用刪除業務方法后,返回到user.html頁面,即當前頁面 location.href = "/userDelete?id=" + id;}function search(){ var name = $("#name").val(); // 調用控制器搜索方法 // 后端邏輯是,控制器調用刪除業務方法后,返回到user.html頁面,即當前頁面 location.href = "/userList?name=" + name;}這是上面user模塊的js文件,user.js,有兩個方法,這個js會被在user.html中引入
但是一個稍微復雜點的系統或功能,不可能只引入這么幾個外部js,常常有幾十個甚至上百個js需要引入,還有我們自己封裝的組件,通用方法等。這樣的大量引入,如果都是user.js 這種全局命名形式,很容易就發生命名上的沖突,就是你定了一個search函數,另一個開發者或者插件里面也定義了一個search方法,這就會帶來莫名奇妙的BUG和問題。
在來看一下資源加載的問題,同樣是用戶模塊,引入了比如說50個js文件,但是有40個文件是點擊搜索時才需要使用,加載列表時不需要,如果每次加載列表都去加載全部的js文件,那將需要多大的帶寬資源和帶來多大的請求壓力(這里先不考慮CDN等優化方式)。能不能讓資源在真正需要的時候再去加載 ?
那么前端模塊化技術就是重點解決以上兩個問題。我們的代碼結構就會變成這個樣子。
定義模塊
define(function(require, exports, module) { var $ = require('jquery'); var tpl = require('template'); var user = {} // 初始化 user.init = function(){ user.deleteUser(); user.search(); } user.deleteUser = function() { $(".delete").click(function(){ $.get('/userDelete?id=' + id,{},function(data){ user.reloadData(); },'json'); }); }; user.search = function() { $("#search").click(function () { var name = $("#name").val(); // 調用控制器搜索方法,返回json數據 $.get('/userList?name=' + name,{},function(data){ var userList = data.userList; var html = template('userListTpl', userList); document.getElementById('userList').innerHTML = html; },'json'); }); }; exports user;});使用模塊
完整頁面代碼
用戶管理用戶添加
用戶姓名:查詢第三代代表技術:seajs、requirejs、kissy
第四代:前端MVC
MVC開始是存在于桌面程序中的,作者意圖解決桌面端GUI的開發耦合問題,后來被結合后端技術,整體又組成了一個MVC模式以及純前端的MVC模式。但思想是一致的,就是包含 控制器、模型、視圖三個部分。
當一個系統的模塊越來越多之后,模塊內部的代碼維護便是個大問題,為了讓模塊代碼變得清晰,更易維護,相互之間沒有緊密的耦合關系,技術先驅者們想了很多解決辦法,MVC便是其中一種,像還有MVP模式,以及后面將提到的MVVM。
第四代代表技術:Extjs、backbone.js
Extjs不是UI框架嗎?,實際上它不只有UI控件,Extjs4開始有了MVC模式,南風哥之前所在公司使用的便是Extjs,充分使用了其中的MVC模式。雖說現在收費了,用的人不怎么多了,但在當年還是有一席之地的。
如何將一個前端模塊使用MVC的方式就行構建,以Extjs的為例構建用戶管理就是如下。
- UserController 注冊用戶管理的交互事件和方法定義
- UserModel 數據模型,配置Store使用
- UserStore 異步請求,負責交互后臺數據
- UserGrid 表格視圖,負責展示Store請求回來的數據,綁定渲染
將各層分離,使代碼整體結構更清晰,耦合度更低,可維護性更強,感覺很復雜?沒錯,這樣本來一個簡單的模塊開發起來就會變得看起來復雜,需要分離,需要遵循一定的規范,但長遠看這么做是有好處的,代碼的可維護性和可讀性會有不小的提升。
第五代: MVVM
這里就不在提MVP這種模式了,沒有太流行起來,直接看MVVM模式。 拆解一下,實際上是 M-V-VM(即模型-視圖-視圖模型)三個部分 ,M和V還是原來的M和V,唯一不同的是VM這個東西,通過VM(ViewModel)完全將M和V分離,是M和V的連接紐帶。實現了雙向數據綁定,簡單理解一下就是,模型發生變化,視圖會自動更新,視圖數據發生變化,模型會自動感知也發生變化,當然這是直觀的使用感受,底層是有比較復雜的實現邏輯支撐。
對開發者來說,就可以從以前的dom操作中解放出來,想想以前的操作模式,接收到后臺的數據,jquery開干,選擇dom,拿到數據,拼接字符串,填充到dom中。視圖數據變化了,js 每次需要主動重新取值,有了MVVM這都不需要了,做好了雙向綁定。只要將數據綁定到M,V自動更新,V層表單或其他視圖組件狀態發生變化,M自動更新,沒有了中間的DOM操作和控制。一切都變得簡單。相互之間也沒有耦合,自己干自己的事情。
相比前端模板引擎,它又少了模板定義這個部分,也是簡單不少,省了不少事情。
使用MVVM后,代碼會變成這樣。
定義
new Vue({ el: '#app', data: { name:'', userList:[] }, methods:{ deleteUser:function(){ }, search:function(){ var _this = this; $.get('/userList?name=' + name,{},function(data){ var userList = data.userList; // 賦值,視圖自動更新 _this.userList = userList; },'json'); } }})使用
用戶管理用戶添加
用戶姓名:查詢 id 姓名 性別 年齡 聯系電話 創建時間 操作 {{user.id}} {{user.name}} {{user.sex}} {{user.age}} {{user.phone}} {{user.createDate}} 刪除第五代代表技術: Angularjs、Vue
第六代:nodejs 為基礎的大前端
關于nodejs引用網上的一句解釋 “Node.js 是一個基于 Chrome V8 引擎的 JavaScript 運行環境。”,簡單的說 Node.js 就是運行在服務端的 JavaScript。What ?js 能運行在服務端了 ?對的。
先說下為什么出現了nodejs這個東西,nodejs作者的初衷是設計一個高性能的Web服務器,讓前端開發人員通過javascript也可以進行服務端的開發,不可否認,事件驅動 + 非阻塞 + Chrome v8 引擎,nodejs的性能表現確實優異。
發展至今,純使用nodejs作為后端開發的企業,顯然不多。但是卻在另外兩個方面大放異彩。
一、開發時,打破前后端協作的壁壘,即使在后端沒有按時提供接口的情況下,前端依舊可以按照自己的節奏完成開發任務。是大前端開發的基石。
二、生產環境中,借助其高性能,更多作為一層網關或代理,轉發請求到真正的后端服務上。
隨著nodejs的流行,前端變得更加獨立,產生了以vue和react為代表的兩大陣營,結合其他插件模塊,前端也有模塊依賴了,也可以管理依賴了,前端也需要打包編譯了,對,沒錯,前端需要學的東西也越來越多了,體系也越來越龐大了,這是真正完全的前后端分離,大前端來了。
第六代代表技術:nodejs、Vue、React、Webpack
通過以上幾代技術的演進,前端技術發展一直在朝著解耦、可維護、高性能的目標不懈的努力著,致力于良好的用戶體驗,未來還會出現哪些NB的技術,讓我們拭目以待吧。
南風哥對以上幾種方式都經歷過,體驗過,現在每種方式肯定都有企業在用或者組合使用,技術這個東西本身就是為解決問題而存在的,不能為了技術而技術,為了追求潮流而不管不顧,立足企業的痛點和需求,結合企業的實際情況,選擇合適的技術解決問題才是王道。
總結
以上是生活随笔為你收集整理的dao模式和前端控制器结合使用_前端技术及开发模式的演进,带你了解前端技术的前世今生...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jenkins 下载插件 一直失败_Je
- 下一篇: 马逊s3云存储接口_利用 S3tests