Springboot3+微服務(wù)實(shí)戰(zhàn)12306高性能售票系統(tǒng)-玉戶簾中卷不去
預(yù)測2024年之后的前端開發(fā)形式
Springboot3+微服務(wù)實(shí)戰(zhàn)12306高性能售票系統(tǒng)
download:https://www.zxit666.com/5932/
最近AIGC(AI Generated Content,應(yīng)用AI生成內(nèi)容)十分熱,技術(shù)圈也遭到了很大沖擊。目前來看,應(yīng)用LLM(Large Language Model,大言語模型)輔助開發(fā)還停留在十分早期的階段,主要應(yīng)用是輔助編碼,即用自然言語輸入需求,模型輸出代碼。更近一步的探究也僅僅是在此根底上的一層封裝(比方copilot X、cursor)。
但即便在如此早期階段,也對開發(fā)者的心智產(chǎn)生極大震動,AI讓程序員失業(yè)這樣的論調(diào)甚囂塵上。
LLM的迸發(fā)對前端意味著什么?本文嘗試預(yù)測一波2024年之后的前端開發(fā)形式,這個預(yù)測遵照如下準(zhǔn)繩:
尊重技術(shù)客觀開展規(guī)律。以當(dāng)前已有技術(shù)為根底預(yù)測,而不是將預(yù)測樹立在某種虛無縹緲的高端技術(shù),或者假想某些技術(shù)打破嚴(yán)重瓶頸
尊重人性。程序員只是營生的職業(yè),新的開發(fā)形式即便再兇猛,假如讓程序員賺不到錢,那也是很難推行開的
范式遷移的實(shí)質(zhì)
為了預(yù)測將來,先看看我們是如何走到如今的。
在前端開發(fā)范疇,我們閱歷了從jQuery為代表的面向過程編程向前端框架為代表的狀態(tài)驅(qū)動形式的遷移。
當(dāng)問到該選Vue還是React開發(fā)?,這樣的問題會惹起很大爭議,但假如問到該選jQuery還是框架開發(fā)?,這樣的問題就不會有太多爭議。
為什么前端范疇普遍承受了這種范式的遷移?在我看來,有兩個緣由:
1. 開發(fā)效率進(jìn)步
這一點(diǎn)毋需多言,置信前端同窗都有領(lǐng)會。
2. 門檻進(jìn)步
面向過程編程是十分粗淺易懂的開發(fā)形式。君不見,曾經(jīng)的前端靠一本尖利的jQuery就能打天下。相比之下,狀態(tài)驅(qū)動就有一定學(xué)習(xí)門檻。
當(dāng)一項(xiàng)有一定門檻的技術(shù)(這里指前端框架)變?yōu)樾袠I(yè)事實(shí)上的規(guī)范時,行業(yè)門檻就提升了,這為從業(yè)者構(gòu)筑了行業(yè)壁壘。
事實(shí)上,正是由于:
web應(yīng)用復(fù)雜度進(jìn)步
前端框架的盛行
才讓后端工程師工作職責(zé)中的view層,分化出前端工程師這一職業(yè)。
關(guān)于前端范疇來說,只要同時均衡了提效與進(jìn)步門檻的技術(shù),才會被市場(這里的消費(fèi)者指前端工程師)承受。
舉個反例,Angular全家桶的形式固然進(jìn)步了開發(fā)效率,但是同時,門檻進(jìn)步太多了。
而且更糟的是,Angular中的很多概念都是從后端遷移而來,作為一款前端框架,對后端更親和且門檻高,這對自身就是從后端view層中分化出的前端工程師來說,是比擬排擠的。
再舉個反例 —— Vue。有同窗會說,Vue這么盛行的前端框架,你說他是反例?
還是從提效與進(jìn)步門檻的角度看,Vue提效的同時,由于其模版語法、響應(yīng)式更新等特性,他是降低了開發(fā)門檻的,這意味著運(yùn)用Vue時:
同樣是開發(fā)業(yè)務(wù),老前端與新前端差距不大
必要時后端經(jīng)過簡單的學(xué)習(xí),也能接手局部需求
重申一下,我并不是說Vue不好,相反,他是很優(yōu)秀的前端框架。這里只是從人性的角度剖析,并且這個剖析很有可能是客觀、帶有成見的。
再看個正面例子 —— React Hooks。Hooks對開發(fā)效率、組件復(fù)用性以及他對React將來開展的影響這里不贅述了。主要聊聊進(jìn)步門檻:
一方面,什么時分封裝自定義Hook,如何封裝自定義Hook,如何躲避Hook的坑,老前端與新前端有比擬大的差別
更重要的是,后端改改JSX還行,要改基于Hooks的組件邏輯,是有一定難度的
既提效,又進(jìn)步門檻,我以為這才是Hooks在前端范疇熾熱的緣由。
同樣的緣由,從人性的角度,我很看好Vue Composition API
所以,前端編程范式遷移的實(shí)質(zhì)是:把握進(jìn)步效率與進(jìn)步門檻之間的均衡。
這個結(jié)論會成為后面預(yù)測將來開發(fā)形式的根據(jù)。
當(dāng)范式無法再遷移時
當(dāng)前端框架成為事實(shí)上的規(guī)范后很長一段時間,業(yè)界也在不時探究新的開發(fā)范式。
有一種開發(fā)形式每過幾年都會被搬出來炒一遍,他就是低代碼。用我們上面的結(jié)論來剖析下:在市場選擇的狀況下,先拋開低代碼能否能進(jìn)步效率不談,顯然他的目的是降低門檻。
從人性的角度動身,他就很難在程序員群體中自發(fā)傳播開。
那么,假如沒有新的范式呈現(xiàn),會發(fā)作什么事情?會內(nèi)卷。
我們會發(fā)現(xiàn),這幾年前端的開展軌跡,就是在反復(fù)一件事:
盤繞前端框架周邊,不時探究各細(xì)分范疇的最佳理論
當(dāng)探究出最佳理論后,就把他集成到框架中
舉個例子,React Router作為React技術(shù)棧中路由這一細(xì)分范疇的一個開源庫,經(jīng)過長期迭代,逐步成為主流路由計(jì)劃之一。
React Router團(tuán)隊(duì)基于React Router開發(fā)出Remix這一React框架。
這么做,在沒有新的范式呈現(xiàn)前,也能基于當(dāng)前范式(前端框架),到達(dá)上述2個目的:
進(jìn)步效率:框架集成了最佳理論,開發(fā)效率更高
進(jìn)步門檻:除了學(xué)習(xí)React,還得學(xué)習(xí)新的上層框架
相似的,各種CSS處理計(jì)劃(比方tailwind css)也是同樣的道理:
進(jìn)步效率:進(jìn)步CSS編寫效率
進(jìn)步門檻:新的概念、語法需求學(xué)習(xí)
那么,將來盤繞進(jìn)步效率與進(jìn)步門檻的均衡,前端開發(fā)形式會如何開展呢?
從思索范式到思索流程
首先,我以為,在有限的將來,不會呈現(xiàn)新的更先進(jìn)的范式能讓前端范疇普遍認(rèn)可并大范圍遷移(就像從jQuery到前端框架的遷移)。
那么,為了進(jìn)步效率,除了改動范式與范式內(nèi) 內(nèi)卷兩個選擇外,還有個選擇 —— 讓整個開發(fā)流程提效。
從需求文檔到最終代碼,存在4級籠統(tǒng):
PM用自然言語編寫的需求文檔
需求評審時,PM給開發(fā)描繪需求后,開發(fā)腦海里構(gòu)成的業(yè)務(wù)邏輯
開發(fā)依據(jù)業(yè)務(wù)邏輯劃分各個模塊或組件
開發(fā)完成各個模塊或組件的詳細(xì)代碼
當(dāng)前我們運(yùn)用LLM輔助編程時(比方以chatGPT為例),主要是用自然言語輸入模塊或組件業(yè)務(wù)邏輯,再讓模型輸出詳細(xì)代碼。也就是借助模型自動完成從3到4級籠統(tǒng)的轉(zhuǎn)變。
比方說下圖我們讓chatGPT完成一個計(jì)時器:
這個計(jì)時器可能是我們需求中的某個模塊,在此chatGPT幫我們完成了從籠統(tǒng)3(完成一個計(jì)時器組件)到籠統(tǒng)4(計(jì)時器組件的代碼)。
假如僅僅到這一步,只能說這是個更高效的輔助工具,并不能到達(dá)整個開發(fā)流程提效的水平。為了到達(dá)這種水平,我們需求讓LLM幫我們完成從籠統(tǒng)1到4的整個過程。
LLM如何完成4級籠統(tǒng)轉(zhuǎn)換
接下來我們來看,基于當(dāng)前已有的模型,如何完成籠統(tǒng)1到籠統(tǒng)4的自動轉(zhuǎn)換。
首先,來看籠統(tǒng)1(PM用自然言語編寫的需求文檔)。chatGPT當(dāng)前曾經(jīng)控制根底的了解才能,所以他是可以了解需求文檔的含義的。
下圖是我從網(wǎng)上找的某需求文檔中的登錄功用流程圖:
以當(dāng)前主流的GPT-3.5舉例,固然GPT-3.5不能了解圖片(不能了解需求文檔中的流程圖),但我們能夠?qū)⒘鞒虉D用文字描繪出來(最新的GPT-4曾經(jīng)具有了解圖片含義的才能)。
上述登錄功用流程圖能夠用文字概括為:
翻開App后有3個選項(xiàng),分別是“賬號密碼登錄”、“快捷登錄”、“第三方登錄”
選擇“第三方登錄”,進(jìn)入第三方,同意受權(quán)后登錄勝利
選擇“快捷登錄”,輸動手機(jī)號和考證碼并選擇身份,點(diǎn)擊登錄后登錄勝利
選擇“賬號密碼登錄”,輸動手機(jī)號,假如已注冊,輸入密碼,點(diǎn)擊登錄后登錄勝利
選擇“賬號密碼登錄”,輸動手機(jī)號,假如未注冊,進(jìn)入注冊頁,輸動手機(jī)號,假如手機(jī)號已注冊,回到“賬號密碼登錄”
選擇“賬號密碼登錄”,輸動手機(jī)號,假如未注冊,進(jìn)入注冊頁,輸動手機(jī)號,假如手機(jī)號未注冊,填寫手機(jī)號、考證碼、密碼、姓名、選擇身份,點(diǎn)擊注冊,終了
籠統(tǒng)1到籠統(tǒng)2
如何完成從籠統(tǒng)1到籠統(tǒng)2(業(yè)務(wù)邏輯)的轉(zhuǎn)變呢?換句話說,如何用一種介于自然言語與實(shí)踐代碼之間的標(biāo)準(zhǔn)描繪業(yè)務(wù)邏輯?
這種標(biāo)準(zhǔn)應(yīng)該具有完備的數(shù)據(jù)構(gòu)造(相似JSON、XML),由于這樣會帶來很多益處:
相比于自然言語,用標(biāo)準(zhǔn)的數(shù)據(jù)構(gòu)造表示的業(yè)務(wù)邏輯可以傳達(dá)更精確的企圖
業(yè)務(wù)需求的不時增加,僅僅對應(yīng)數(shù)據(jù)構(gòu)造體積的增大,即便再復(fù)雜的業(yè)務(wù),只需求分批將業(yè)務(wù)邏輯代表的數(shù)據(jù)構(gòu)造投喂給模型,模型就能完整了解我們的業(yè)務(wù)
數(shù)據(jù)構(gòu)造能夠保管在變量中,經(jīng)過變量名就能指代業(yè)務(wù)邏輯,無需再用自然言語大段的向模型描繪業(yè)務(wù)邏輯
我們能夠應(yīng)用SCXML(State Chart XML)格式。SCXML是由W3C定義的一種表示狀態(tài)機(jī)的XML格式,他可以表示狀態(tài)之間的變化。
前端應(yīng)用的實(shí)質(zhì)其實(shí)就包括兩局部:
狀態(tài)的變化
狀態(tài)到視圖的映射
其中狀態(tài)到視圖的映射框架曾經(jīng)幫我們做了。所以,只需能表示狀態(tài)的變化,其實(shí)就能表示業(yè)務(wù)邏輯。
如今,我們讓chatGPT將流程圖翻譯為SCXML格式:
得到如下構(gòu)造(你不用細(xì)看,理解個大約就行):
<scxml version="1.0" xmlns="http://www.w3.org/2005/07/scxml">
<state id="mainMenu">
<transition event="THIRD_PARTY_LOGIN" target="thirdPartyLogin" />
<transition event="QUICK_LOGIN" target="quickLogin" />
<transition event="ACCOUNT_LOGIN" target="accountLogin" />
</state>
<state id="thirdPartyLogin">
<onentry>
<send event="AGREE_AUTHORIZATION" />
<send event="LOGIN_SUCCESS" />
</onentry>
</state>
<state id="quickLogin">
<onentry>
<send event="INPUT_PHONE_NUMBER" />
<send event="INPUT_VERIFICATION_CODE" />
<send event="SELECT_IDENTITY" />
<send event="LOGIN_SUCCESS" />
</onentry>
</state>
<state id="accountLogin">
<state id="inputPhoneNumber">
<transition event="PHONE_NUMBER_SUBMITTED" target="checkRegistered" />
</state>
<state id="checkRegistered">
<onentry>
<send event="CHECK_REGISTERED" />
</onentry>
<transition event="REGISTERED" target="inputPassword" />
<transition event="UNREGISTERED" target="register" />
</state>
<state id="inputPassword">
<onentry>
<send event="INPUT_PASSWORD" />
<send event="LOGIN_SUCCESS" />
</onentry>
</state>
<state id="register">
<state id="inputPhoneNumber">
<transition event="PHONE_NUMBER_SUBMITTED" target="checkRegistered" />
</state>
<state id="checkRegistered">
<onentry>
<send event="CHECK_REGISTERED" />
</onentry>
<transition event="REGISTERED" target="inputPassword" />
<transition event="UNREGISTERED" target="inputUserInfo" />
</state>
<state id="inputUserInfo">
<onentry>
<send event="INPUT_PHONE_NUMBER" />
<send event="INPUT_VERIFICATION_CODE" />
<send event="INPUT_PASSWORD" />
<send event="INPUT_NAME" />
<send event="SELECT_IDENTITY" />
<send event="REGISTER_SUCCESS" />
</onentry>
</state>
</state>
</state>
</scxml>
至此,我們完成了籠統(tǒng)1到籠統(tǒng)2的轉(zhuǎn)變。
籠統(tǒng)2到籠統(tǒng)3
SCXML格式?jīng)]法直接在JS代碼中運(yùn)用。為了用代碼完成邏輯,我們需求運(yùn)用遵照SCXML標(biāo)準(zhǔn)的庫。xstate是JS中比擬盛行的狀態(tài)機(jī)開源庫。
所以接下來我們讓chatGPT將上述SCXML格式轉(zhuǎn)換為xstate語法:
得到結(jié)果(同樣,詳細(xì)代碼你不用在意,理解我想表達(dá)的轉(zhuǎn)換意義就行):
import { Machine, sendParent } from 'xstate';
const loginMachine = Machine({
id: 'login',
initial: 'mainMenu',
states: {
mainMenu: {
on: {
THIRD_PARTY_LOGIN: 'thirdPartyLogin',
QUICK_LOGIN: 'quickLogin',
ACCOUNT_LOGIN: 'accountLogin'
}
},
thirdPartyLogin: {
onEntry: [
sendParent('AGREE_AUTHORIZATION'),
sendParent('LOGIN_SUCCESS')
]
},
quickLogin: {
onEntry: [
sendParent('INPUT_PHONE_NUMBER'),
sendParent('INPUT_VERIFICATION_CODE'),
sendParent('SELECT_IDENTITY'),
sendParent('LOGIN_SUCCESS')
]
},
accountLogin: {
initial: 'inputPhoneNumber',
states: {
inputPhoneNumber: {
on: {
PHONE_NUMBER_SUBMITTED: 'checkRegistered'
}
},
checkRegistered: {
onEntry: sendParent('CHECK_REGISTERED'),
on: {
REGISTERED: 'inputPassword',
UNREGISTERED: 'register.inputPhoneNumber'
}
},
inputPassword: {
onEntry: [
sendParent('INPUT_PASSWORD'),
sendParent('LOGIN_SUCCESS')
]
},
register: {
initial: 'inputPhoneNumber',
states: {
inputPhoneNumber: {
on: {
PHONE_NUMBER_SUBMITTED: 'checkRegistered'
}
},
checkRegistered: {
onEntry: sendParent('CHECK_REGISTERED'),
on: {
REGISTERED: 'inputPassword',
UNREGISTERED: 'inputUserInfo'
}
},
inputPassword: {
onEntry: [
sendParent('INPUT_PASSWORD'),
sendParent('REGISTER_SUCCESS')
]
},
inputUserInfo: {
onEntry: [
sendParent('INPUT_PHONE_NUMBER'),
sendParent('INPUT_VERIFICATION_CODE'),
sendParent('INPUT_PASSWORD'),
sendParent('INPUT_NAME'),
sendParent('SELECT_IDENTITY'),
sendParent('REGISTER_SUCCESS')
]
}
}
}
}
}
}
});
export default loginMachine;
初始狀態(tài)能夠轉(zhuǎn)移到3個狀態(tài)(這些狀態(tài)都是chatGPT生成的),其中:
QUICK_LOGIN —— 快捷登錄
ACCOUNT_LOGIN —— 賬號密碼登錄
THIRD_PARTY_LOGIN —— 第三方登錄
每個狀態(tài)接下來的變化邏輯都明晰可見。比方,當(dāng)進(jìn)入ACCOUNT_LOGIN狀態(tài)后,后續(xù)會依據(jù)能否登錄(UNREGISTERED、REGISTERED)進(jìn)入不同邏輯:
也就是說,chatGPT了解了需求文檔想表達(dá)的業(yè)務(wù)邏輯后,將業(yè)務(wù)邏輯轉(zhuǎn)換成代碼表示。
讀者可將上述xstate代碼復(fù)制到可視化編輯器中看到效果
籠統(tǒng)3到籠統(tǒng)4
接下來,我們只需求讓chatGPT依據(jù)上述xstate狀態(tài)機(jī)生成組件代碼即可。
這時有同窗會問:chatGPT對話有token限制,沒法生成太多代碼怎樣辦?
實(shí)踐上,這可能并不是壞事。在我曾經(jīng)供職的一家公司,前端團(tuán)隊(duì)有條不成文的規(guī)矩 —— 假如一個組件超越200行,那你就應(yīng)該拆分他。
同樣的,假如chatGPT生成的組件超越了token限制,那么應(yīng)該讓他拆分新的組件。
拆分組件的前提是 —— chatGPT需求懂業(yè)務(wù)邏輯。顯然,他曾經(jīng)懂了xstate數(shù)據(jù)構(gòu)造所代表的業(yè)務(wù)邏輯。
更妙的是,我們能夠讓chatGPT將SCXML格式轉(zhuǎn)換而來的xstate數(shù)據(jù)構(gòu)造保管在一個變量中,在后續(xù)對話中,我們用一個變量名就能指代他背后所表示的業(yè)務(wù)邏輯(這里保管在變量m中)。
當(dāng)我們要生成業(yè)務(wù)組件代碼時,讓chatGPT從模塊中導(dǎo)出m完成組件邏輯:
關(guān)于實(shí)踐場景下比擬復(fù)雜的需求,經(jīng)過從籠統(tǒng)1到籠統(tǒng)3的轉(zhuǎn)換,我們會得到代表業(yè)務(wù)邏輯的不同變量,比方:
signin變量代表登錄邏輯
login變量代表注冊邏輯
PopupAD變量代表彈窗廣告邏輯
假如彈窗廣告的邏輯和能否登錄相關(guān),那么要完成彈窗廣告組件代碼只需求通知chatGPT:
依據(jù)signin、PopupAD完成彈窗廣告的react組件,其中signin變量由xxx模塊導(dǎo)出,PopupAD變量由yyy導(dǎo)出。
假如你司運(yùn)用其他框架,只需將其中react換成其他框架名即可。當(dāng)大家還在爭論哪個框架更優(yōu)秀時,LLM曾經(jīng)悄然幫開發(fā)者完成了框架自在。
新開發(fā)形式的優(yōu)勢
讓我們從進(jìn)步效率與進(jìn)步門檻的角度剖析這種新開發(fā)形式的優(yōu)勢。
進(jìn)步效率
首先,這種新形式能顯著進(jìn)步開發(fā)效率。實(shí)質(zhì)來說,他將前端工程師從完成需求的角色轉(zhuǎn)變?yōu)閞eview代碼的角色。
極端的講,當(dāng)需求評審會完畢的那一刻,第一版前端代碼就生成了。
其次,他能解放局部測試同窗的消費(fèi)力(搶局部測試同窗的活兒)。關(guān)于維護(hù)過屎山代碼的同窗,肯定遇到過這樣的場景:明明只是改動一個小需求,測試問你改動影響的范圍,你本人都不分明會有多大影響,為了穩(wěn)妥起見只能讓測試掩蓋更大的回歸測試范圍。
在運(yùn)用基于狀態(tài)機(jī)的開發(fā)形式后,任何改動會形成的影響在狀態(tài)圖中都明晰可見。同時,由于代碼邏輯的完成基于狀態(tài)機(jī),能夠據(jù)此自動生成端到端的測試用例,模型也能依據(jù)狀態(tài)機(jī)描繪的邏輯本人補(bǔ)足其他單測。
進(jìn)步門檻
接下來,我們從進(jìn)步門檻的角度剖析。
首先,可以對模型生成的代碼停止查漏補(bǔ)缺自身就請求開發(fā)者有一定前端開發(fā)程度。
其次,這種開發(fā)形式引入了新的籠統(tǒng)層 —— 狀態(tài)機(jī),這無疑會增加上手門檻。
但這都不是最重要的,最重要的是 —— 這套形式強(qiáng)迫前端開發(fā)需求更懂業(yè)務(wù)。
以前,拿到產(chǎn)品的需求文檔后,你能夠在做的過程中遇到不懂的再問產(chǎn)品。運(yùn)用新的開發(fā)形式后,你必需很懂業(yè)務(wù),做到在需求評審時就能指出需求文檔中不合理的中央。
由于當(dāng)需求評審?fù)戤吅?,你會將這份需求文檔投喂給模型直接生成業(yè)務(wù)代碼(中間會閱歷生成SCXML、生成xstate數(shù)據(jù)構(gòu)造、保管xstate變量、運(yùn)用變量生成組件代碼)。
當(dāng)大家技術(shù)程度旗鼓相當(dāng)時,懂業(yè)務(wù)才是前端的中心競爭力。
綜上,這套開發(fā)形式在極大進(jìn)步效率的同時進(jìn)步了門檻,我以為在將來很有可能成為主流前端開發(fā)形式。