好的架構(gòu)來自于演化坐求,人亦之。
在公司做全棧工程師晌梨,一年的磨練桥嗤,讓我在開發(fā)道路上也有了長(zhǎng)足的進(jìn)步。現(xiàn)在仔蝌,組里來了一些新員工泛领,為了幫助他們更好的理解web開發(fā),就寫了這篇文章敛惊,也全當(dāng)自己一年的“演進(jìn)”吧渊鞋。
目的
- web開發(fā),是組內(nèi)的工作之一豆混,希望同事們對(duì)web開發(fā)有一些共同的認(rèn)識(shí)篓像,也歡迎讀者拍磚(keypoint:前后端的分離)
web的演化之路
什么是web開發(fā)?
Web開發(fā)皿伺,一種基于B/S架構(gòu)(BROWSER/SERVER)的應(yīng)用軟件開發(fā)技術(shù)员辩,分為前端(用戶接口)和后端(業(yè)務(wù)邏輯和數(shù)據(jù))。
簡(jiǎn)單介紹一下技術(shù):
- 前端:HTML(負(fù)責(zé)框架)鸵鸥,CSS(負(fù)責(zé)樣式)奠滑,JavaScript(負(fù)責(zé)交互)【載體:瀏覽器丹皱。HTML、CSS渲染引擎宋税,JS解釋器摊崭,還有一些別的,比如客戶端數(shù)據(jù)庫】
- 后端:PHP杰赛,JAVA呢簸,PYTHON等等》ν停【載體:python解釋器根时,java編譯器,Apache】
- OSI模型:物理層辰晕,數(shù)據(jù)鏈路層【SDLC】蛤迎,網(wǎng)絡(luò)層【IP】,傳輸層【TCP含友、UDP】替裆,會(huì)話層,表示層窘问,應(yīng)用層【HTTP】(理論共七層)
在整個(gè)互聯(lián)網(wǎng)的發(fā)展過程中辆童,web的演化是非常漫長(zhǎng)的,也伴隨著技術(shù)的迭代南缓。而在我們小組胸遇,這個(gè)過程是簡(jiǎn)單并且清晰的,我從一年眾多的工作中找到這樣一條web演化的路線汉形,希望能夠幫助同事們更加理解團(tuán)隊(duì)的技術(shù)架構(gòu)纸镊。
v1.0
背景故事:
為了驗(yàn)證某項(xiàng)業(yè)務(wù)的有效性,我們啟動(dòng)了魔鏡項(xiàng)目概疆,第一個(gè)階段是build一個(gè)能夠讓實(shí)習(xí)生標(biāo)記tag的平臺(tái)逗威。這就是小組WEB開發(fā)的開端,我們選擇python為基礎(chǔ)的技術(shù)棧岔冀,試用Flask凯旭,然后就做出了第一個(gè)頁面。
代碼工具: mp
Jinja2使套。Flask自帶的頁面渲染模塊混聊,它被最常使用的就是變量傳遞和控制結(jié)構(gòu)罩锐。
# hello.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
user = {"Xing": "Ming", "Nian": "Ling"}
cool_here = "Thanks for reading!"
return render_template('index.html', user=user, cool_here=cool_here)
app.run()
# index.html
<h1>Hello World!</h1>
{% for key, value in user.items() %}
<h1>{{ key }}</h1>
<h2>{{ value }}</h2>
{% endfor %}
{{ cool_here }}
看代碼斟薇,很容易就能發(fā)現(xiàn)Jinja2模版引擎的優(yōu)勢(shì)胖眷,它可以讓你像寫python一樣寫HTML頁面,通過python解釋器轉(zhuǎn)化出整個(gè)HTML的DOM樹奉呛,從而實(shí)現(xiàn)web開發(fā)计螺。
在這個(gè)階段夯尽,沒有什么前后端的區(qū)分,大家都在寫后端代碼登馒,所有的控制都在服務(wù)端完成匙握,瀏覽器只用渲染后端提供的頁面數(shù)據(jù)就可以了。
再補(bǔ)充一點(diǎn)關(guān)于數(shù)據(jù)傳遞(POST陈轿, GET)的代碼圈纺。
<form id='user_form' name='user_form' method='post' action='{{ url_for('user.add_user') }}'>
<tr id='hidden-tr'>
<td><input type='text' name='username'>
<td><input pattern='[0, 1, 2, 4]' name='permission' value=1> <!--數(shù)據(jù)校驗(yàn)-->
<td><input type='submit' class='like' value='增加&更新'>
</tr>
</form>
<a href="{{ url_for(link_url, sid=sid) }}" name='card-link'>{{ link_name }}</a>
明顯特點(diǎn):
- 小巧的Flask以一己之力從后到前的實(shí)現(xiàn)了當(dāng)時(shí)業(yè)務(wù)的需求,魔鏡平臺(tái)有條不紊的被搭建起來;
- 技術(shù)棧簡(jiǎn)單輕巧麦射,團(tuán)隊(duì)能夠在開發(fā)時(shí)有余力做模型建立和業(yè)務(wù)探索赠堵。
典型問題:
- 業(yè)務(wù)變得復(fù)雜。在一個(gè)頁面內(nèi)點(diǎn)擊一個(gè)按鈕法褥,發(fā)出一個(gè)request但不reload頁面,這套簡(jiǎn)單的開發(fā)模式根本無法實(shí)現(xiàn)類似的需求酬屉;
- 代碼難維護(hù)半等。隨著前端業(yè)務(wù)變得復(fù)雜,為了響應(yīng)變動(dòng)的前端業(yè)務(wù)呐萨,后端要付出的成本急劇增大杀饵,代碼職責(zé)也變得不清晰起來;
- 交互體驗(yàn)谬擦。改善用戶每次校驗(yàn)數(shù)據(jù)需要把數(shù)據(jù)傳到服務(wù)器端的窘境切距。
v2.0
背景故事:
為了響應(yīng)復(fù)雜的業(yè)務(wù)需求,我們必須在頁面中使用ajax惨远。JavaScript的加入谜悟,讓前后端變得分明,也讓代碼職責(zé)重新變得清晰北秽。頁面的局部交互全部由ajax完成葡幸,部分?jǐn)?shù)據(jù)校驗(yàn)也由ajax完成,這時(shí)候是前后端分庭抗禮的階段贺氓。
代碼工具:
Jquery蔚叨,脫穎而出的JavaScript庫,依賴簡(jiǎn)單的CDN就能完美使用辙培,它被最常使用的是事件響應(yīng)和ajax交互蔑水。
<script src="{{ url_for('static',filename='jquery-3.2.1.min.js') }}"></script>
<script>
$("#btn_input_form").on("click",function(){
console.info("show a form");
$("#div_input").show();
})
$.ajax({
url: postUrl,
data: formData,
processData: false,
contentType: "application/json",
type: 'POST',
success: function (data) {
// do something
}
})
</script>
明顯特點(diǎn):
- 滿足了需求,頁面的功能逐漸飽滿扬蕊;
- 前后分明搀别,在某種程度上簡(jiǎn)化了后端代碼的復(fù)雜度,讓代碼維護(hù)變得輕松厨相。
典型問題:
- 有Jinja2模版的支持领曼,jquery操作DOM起來得心應(yīng)手鸥鹉,但是jquery以功能交互為主,前端代碼很快變得十分龐大庶骄,文件變得冗長(zhǎng)毁渗,閱讀困難倍增,維護(hù)亦然单刁;
- 業(yè)務(wù)不斷的迭代灸异,對(duì)web頁面的需求也不斷拔高,jinja頁面和ajax的配合逐漸不能滿足日益增長(zhǎng)的交互需求羔飞,新的技術(shù)擴(kuò)展需求迫在眉睫肺樟;
- 后端業(yè)務(wù)的不斷擴(kuò)展,前端相同的交互功能代碼逻淌,抽象和復(fù)用都很難進(jìn)行么伯,這幾乎成為了制約前端進(jìn)步的主要原因。
v3.0
背景故事:
為了響應(yīng)復(fù)雜的業(yè)務(wù)需求卡儒,團(tuán)隊(duì)進(jìn)一步踐行SPA(single-page application)田柔,把大量的業(yè)務(wù)需求放在前端實(shí)現(xiàn),進(jìn)一步增加前端交互功能并且優(yōu)化用戶體驗(yàn)骨望,推行了Vue框架硬爆。至此,組內(nèi)的web開發(fā)已向前端傾斜擎鸠。
代碼工具:
Vue缀磕,構(gòu)建用戶界面的漸進(jìn)式框架,它的核心庫只關(guān)注頁面本身劣光,易于上手袜蚕,方便集成。
<div id="demoPage">
<h4> 請(qǐng)選擇:你更喜歡哪一個(gè)還原過程呢绢涡?</h4>
<form>
<textarea v-model="comment" v-if='showOrHide' v-bind:placeholder="warnMsg"></textarea>
<button type="button" @click="makeDecision()">我選好了廷没!</button>
</form>
</div>
var app = new Vue({
el: "#demoPage",
data: {
showOrHide: true,
comment: '',
warnMsg: '請(qǐng)輸入理由!',
},
methods: {
makeDecision: function() {
let that = this;
if (that.chosenValue === null && that.comment === "") {
var msgArray = ["要輸入理由哦~", "請(qǐng)務(wù)必告知原因~"];
that.warnMsg = msgArray[Math.floor(Math.random() * msgArray.length)];
return
};
$.ajax({
// do something
})
},
},
})
看代碼垂寥,很容易知道Vue不僅在script層做交互颠黎,它綁定了DOM,實(shí)現(xiàn)了數(shù)據(jù)的雙向綁定滞项。各種語法和組件也易于使用狭归,還有簡(jiǎn)單方便的打包工具,也給一段組件化的示例文判。
<template>
</template>
<script>
</script>
<style scoped>
</style>
明顯特點(diǎn):
- 虛擬的DOM过椎,雙向綁定的數(shù)據(jù),組件化的視圖戏仓,簡(jiǎn)單的語法疚宇,Vue極大的滿足了團(tuán)隊(duì)的前端需求亡鼠,幾乎對(duì)接了企業(yè)級(jí)的前端應(yīng)用;
- 徹底分開的前后端架構(gòu)敷待,職責(zé)更清晰间涵,開發(fā)更容易,維護(hù)更簡(jiǎn)單榜揖;
- 部署相對(duì)獨(dú)立勾哩,產(chǎn)品體驗(yàn)可以快速改進(jìn)。
典型問題:
- API不清楚举哟。隨著前后端的分離思劳,所有鏈接變成API,那API的穩(wěn)定和清晰就至關(guān)重要了妨猩。前端靜態(tài)化潜叛、后端數(shù)據(jù)化、構(gòu)架分離化壶硅,三大轉(zhuǎn)變演進(jìn)緩慢钠导,導(dǎo)致團(tuán)隊(duì)配合失調(diào)∩瘢【前后端分離最困難、最關(guān)鍵的環(huán)節(jié)票堵,API的制定和編寫扼睬。】
- 設(shè)計(jì)階段:架構(gòu)負(fù)責(zé)人對(duì)項(xiàng)目整體進(jìn)行分析悴势,討論并確定API風(fēng)格窗宇,制定API接口;
- 開發(fā)階段:前后端分離各自分工特纤,后端提供數(shù)據(jù)API军俊,并撰寫文檔,前端獲取數(shù)據(jù)捧存;
- 測(cè)試階段:(mock測(cè)試)前后端擬定測(cè)試時(shí)間粪躬,迅速調(diào)整接口。
- SPA并不能滿足所有需求昔穴,依舊存在大量多頁面應(yīng)用镰官,某些design仍然需要后端配合。
Future
團(tuán)隊(duì)的web開發(fā)演化到了今天吗货,幾乎發(fā)生了滄海桑田的變化泳唠。但是,演化并沒有走到盡頭...
變美的關(guān)鍵-CSS
我們選用了bootstrap作為樣式庫宙搬。
結(jié)語
由于小組是以全棧為目的進(jìn)行組建的笨腥,在前后端的處理上有很多麻煩拓哺,很多工作在前后端都能完成,所以職責(zé)不明晰脖母、代碼不簡(jiǎn)潔成為了web開發(fā)的主要問題士鸥。SPA讓后端數(shù)據(jù)化確實(shí)給了我們很大的幫助。
最后镶奉,非常感謝花時(shí)間閱讀文章的你們础淤,非常歡迎大家指出我意識(shí)不到的BUG,如果有幫助到大家哨苛,也非常喜歡大家順手點(diǎn)個(gè)贊鸽凶!