(二)架构基础知识
軟件設(shè)計(jì)原則與分層
軟件設(shè)計(jì)原則
單一職責(zé)原則
永遠(yuǎn)不應(yīng)該有多余一個(gè)原因來改變某個(gè)類
理解:對(duì)于一個(gè)類而言,應(yīng)該僅有一個(gè)引起它變化的原因
應(yīng)用:如果一個(gè)類擁有了兩種職責(zé),那就可以將這個(gè)類分成兩個(gè)類
開放封閉原則
軟件實(shí)體擴(kuò)展應(yīng)該是開放的,但對(duì)于修改應(yīng)該是封閉的
理解:對(duì)擴(kuò)展開放,對(duì)修改封閉,可以去擴(kuò)展類,但不要去修改類
應(yīng)用:當(dāng)需求有改動(dòng),盡量用繼承或組合的方式來擴(kuò)展類的功能,而不是直接修改類的代碼
里氏替換原則
理解:父類一定能夠被子類替換
最少知識(shí)原則
只與你最直接的對(duì)象交流
理解:低耦合,高內(nèi)聚
應(yīng)用:做系統(tǒng)設(shè)計(jì)時(shí),盡量減少依賴關(guān)系
接口隔離原則
一個(gè)類與另一個(gè)類之間的依賴性,應(yīng)該依賴于盡可能小的接口
理解:不要對(duì)外暴露沒有實(shí)際意義的接口。用戶不應(yīng)該依賴它不需要的接口
應(yīng)用:當(dāng)需要對(duì)外暴露接口時(shí),如果是非必要對(duì)外提供,盡量刪除
依賴倒置原則
高層模塊不應(yīng)該依賴低層模塊,它們應(yīng)該依賴于抽象。抽象不應(yīng)該依賴于細(xì)節(jié),細(xì)節(jié)應(yīng)該依賴于抽象
理解:應(yīng)該面向接口編程,不應(yīng)該面向?qū)崿F(xiàn)類編程
并不是說,所有的類都要有一個(gè)對(duì)應(yīng)的接口,而是說,如果有接口,那就盡量使用接口來編程吧
總結(jié)
將以上六大原則的英文首字母拼在一起就是SOLID(穩(wěn)定的),所以也稱之為SOLID原則
只有滿足了這六大原則,才能設(shè)計(jì)出穩(wěn)定的軟件架構(gòu)!
補(bǔ)充設(shè)計(jì)原則
- 組合/聚合復(fù)用原則
當(dāng)要擴(kuò)展類的功能時(shí),優(yōu)先考慮使用組合,而不是繼承
該原則在23中典型設(shè)計(jì)模式中頻繁使用
如:代理模式、裝飾模式、適配器模式等 - 無環(huán)依賴原則
當(dāng)A模塊依賴于B模塊,B模塊依賴于C模塊,C模塊依賴于A模塊,此時(shí)將出現(xiàn)循環(huán)依賴
在設(shè)計(jì)中避免該問題,可通過引入“中介者模式”解決 - 共同封裝原則
應(yīng)該將易變的類放在同一個(gè)包里,將變化隔離出來
該原則是“開放-封閉原則”的誕生 - 共同重用原則
如果重用了包中的一個(gè)類,那么也就相當(dāng)于重用了包中的所有類,我們要盡可能減少包的大小 - 好萊塢原則
Don"t call me, I"ll call you
“控制反轉(zhuǎn)”(或稱為“依賴注入”)
不需要主動(dòng)創(chuàng)建對(duì)象,而是由容器幫我們來創(chuàng)建并管理這些對(duì)象 - 不重復(fù)原則
不要讓重復(fù)的代碼到處都是,要讓它們足夠的重用,所以要盡可能地封裝 - 保持它簡(jiǎn)單與傻瓜
保持系統(tǒng)界面簡(jiǎn)潔,功能實(shí)用,操作方便 - 高內(nèi)聚與低耦合
模塊內(nèi)部需要做到內(nèi)聚度高,模塊之間需要做到耦合度低 - 關(guān)注點(diǎn)分離
將一個(gè)復(fù)雜的問題分離為多個(gè)簡(jiǎn)單的問題,然后逐個(gè)解決
難點(diǎn):如何進(jìn)行分離 - 你不需要它
不要一開始就把系統(tǒng)設(shè)計(jì)得非常復(fù)雜,不要陷入“過度設(shè)計(jì)”的深淵
讓系統(tǒng)足夠簡(jiǎn)單,而不失擴(kuò)展性
軟件設(shè)計(jì)分層
架構(gòu)種類分為:系統(tǒng)級(jí)架構(gòu)、應(yīng)用級(jí)架構(gòu)、代碼級(jí)架構(gòu)、模塊級(jí)架構(gòu)
系統(tǒng)級(jí)架構(gòu)
應(yīng)用在整個(gè)系統(tǒng)內(nèi),如后臺(tái)服務(wù)如何通信,與第三方系統(tǒng)如何集成
設(shè)計(jì)前端首要條件:了解前端系統(tǒng)與其他系統(tǒng)之間的關(guān)系
關(guān)系包括:業(yè)務(wù)關(guān)系和協(xié)作機(jī)制
設(shè)計(jì)后端:只需要規(guī)定與后臺(tái)數(shù)據(jù)傳遞的機(jī)制
包括:api設(shè)計(jì)規(guī)則,訪問授權(quán)的一個(gè)開放標(biāo)準(zhǔn)(OAuth)跳轉(zhuǎn)token的驗(yàn)證,數(shù)據(jù)傳遞cookie等。
前端和后端的關(guān)系考慮的主要因素是:前后端分離的架構(gòu)設(shè)計(jì)。
前后端分離架構(gòu)其實(shí)是如何實(shí)施技術(shù)決策,用戶鑒權(quán)、API接口管理和設(shè)計(jì)、API文檔管理、Mock的使用、BFF(服務(wù)于前端的后端,nodejs),是否需要服務(wù)端渲染等
微前端
在一個(gè)系統(tǒng)內(nèi)微前端是應(yīng)用間的架構(gòu)方案
在多個(gè)應(yīng)用之間,微前端則是一種系統(tǒng)間等架構(gòu)方案
微前端是將多個(gè)前端應(yīng)用以某種形式結(jié)合在一起進(jìn)行應(yīng)用
旨在解決單體應(yīng)用在一個(gè)相對(duì)長(zhǎng)的時(shí)間跨度下,由于參與的人員、團(tuán)隊(duì)的增多、變遷,從一個(gè)普通應(yīng)用演變成一個(gè)巨石應(yīng)用(Frontend Monolith)后,隨之而來的應(yīng)用不可維護(hù)的問題。
單實(shí)例:即同一時(shí)刻,只有一個(gè)子應(yīng)用被展示,子應(yīng)用具備一個(gè)完整的應(yīng)用生命周期
多實(shí)例:通常基于url的變化來做子應(yīng)用的切換。
多實(shí)例子:同一時(shí)刻可展示多個(gè)子應(yīng)用。
通常使用Web Components方案來做子應(yīng)用封裝,子應(yīng)用更像是一個(gè)業(yè)務(wù)組件而不是應(yīng)用
應(yīng)用級(jí)架構(gòu)
應(yīng)用級(jí)架構(gòu)可以看作是系統(tǒng)級(jí)架構(gòu)的細(xì)化
單個(gè)應(yīng)用與其他外部應(yīng)用的關(guān)系,微服務(wù)架構(gòu)下多個(gè)應(yīng)用的協(xié)作,數(shù)據(jù)交換等
腳手架、模式庫、設(shè)計(jì)系統(tǒng)
模塊級(jí)架構(gòu)
這部分內(nèi)容是我們開始業(yè)務(wù)編碼之前進(jìn)行設(shè)計(jì),我們稱為迭代。
代碼級(jí)架構(gòu)
規(guī)范與原則
實(shí)操
開發(fā)流程
代碼質(zhì)量以及改善
規(guī)范而非默契
注:
在開發(fā)中,要注意可維護(hù)性
簡(jiǎn)單的代碼可維護(hù)性高,越是寫的抽象的代碼越難維護(hù)
如何保證架構(gòu)的質(zhì)量
系統(tǒng)的穩(wěn)定性
定義:當(dāng)一個(gè)實(shí)際的系統(tǒng)處于一個(gè)平衡的狀態(tài)時(shí),如果受到外來作用的影響時(shí),系統(tǒng)經(jīng)過一個(gè)過濾過程仍然能夠回到原來的平衡狀態(tài),我們就稱這個(gè)系統(tǒng)就是穩(wěn)定的,否則稱系統(tǒng)不穩(wěn)定
架構(gòu)設(shè)計(jì)的基石
可以更好的實(shí)現(xiàn)自我修復(fù)
系統(tǒng)的健壯性
定義:計(jì)算機(jī)軟件在輸入錯(cuò)誤、磁盤故障、網(wǎng)絡(luò)過載或有意攻擊情況下,能否不死機(jī)、不崩潰,就是該軟件健壯性的具體表現(xiàn)。
解釋:一個(gè)系統(tǒng)容錯(cuò)能力強(qiáng),運(yùn)行不易被干擾,安全性好
系統(tǒng)的健壯性的度量標(biāo)準(zhǔn)
一個(gè)軟件可以從錯(cuò)誤的輸入推斷出正確合理的輸入
一個(gè)軟件可以正確的運(yùn)行在不同環(huán)境下
一個(gè)軟件能夠檢測(cè)自己內(nèi)部的設(shè)計(jì)或者編碼錯(cuò)誤,并得到正確的結(jié)果
系統(tǒng)的健壯性和穩(wěn)定性
健壯性和穩(wěn)定性是特定的軟件自身的要求
健壯性和穩(wěn)定性是軟件處理的一部分
軟件架構(gòu)的健壯性和穩(wěn)定性是該軟件規(guī)劃時(shí)所確定的目標(biāo)
若軟件的實(shí)現(xiàn)未達(dá)原定目標(biāo),則該軟件的健壯性和穩(wěn)定性不夠或不好
架構(gòu)質(zhì)量的衡量
擴(kuò)展性
可管理
維護(hù)性
高可用(故障修復(fù)、容災(zāi)、降級(jí)、熔斷)
日常開發(fā)過程中的架構(gòu)質(zhì)量
理解難度
崩潰率和錯(cuò)誤率的指標(biāo)
接入依賴的成本
開發(fā)效率
錯(cuò)誤上報(bào)和信息收集等功能
架構(gòu)前期準(zhǔn)備
架構(gòu)師分類
系統(tǒng)架構(gòu)師,應(yīng)用架構(gòu)師、業(yè)務(wù)架構(gòu)師
系統(tǒng)架構(gòu)師
從系統(tǒng)的維度,負(fù)責(zé)整體系統(tǒng)的架構(gòu)設(shè)計(jì)
主要是基礎(chǔ)服務(wù)和各系統(tǒng)間協(xié)調(diào),著眼全局
比如關(guān)注負(fù)載,可靠性,伸縮,擴(kuò)展,整體項(xiàng)目切分,緩存應(yīng)用等方面的基礎(chǔ)架構(gòu)設(shè)計(jì)
應(yīng)用架構(gòu)師
從應(yīng)用程序的維度,負(fù)責(zé)某個(gè)應(yīng)用的技術(shù)架構(gòu),主要偏業(yè)務(wù)系統(tǒng)
關(guān)注理解業(yè)務(wù),梳理模型,設(shè)計(jì)模式,接口,數(shù)據(jù)交互等方面
業(yè)務(wù)架構(gòu)師
從業(yè)務(wù)流程的維度,關(guān)注某一個(gè)行業(yè)、業(yè)務(wù)的領(lǐng)域分析,獲取領(lǐng)域模型,最終獲得系統(tǒng)的模型
也可以叫業(yè)務(wù)領(lǐng)域?qū)<摇⑿袠I(yè)專家、產(chǎn)品咨詢師、資深顧問
技術(shù)前期準(zhǔn)備
技術(shù)選型:社區(qū)氛圍、發(fā)展規(guī)律、未來發(fā)展趨勢(shì)、與當(dāng)前團(tuán)隊(duì)的契合度、執(zhí)行成本、維護(hù)和遷移成本、執(zhí)行效率等內(nèi)容的調(diào)研和報(bào)告
充分調(diào)研每一項(xiàng)技術(shù)可能帶來的利與弊
最大程度上預(yù)測(cè)架構(gòu)設(shè)計(jì)中的缺陷,以防止問題的發(fā)生
技術(shù)優(yōu)化
在架構(gòu)發(fā)展過程中,可能會(huì)存在一些有悖于當(dāng)前架構(gòu)設(shè)計(jì)的實(shí)現(xiàn),造成了架構(gòu)發(fā)展阻塞,所以需要進(jìn)行架構(gòu)優(yōu)化,使架構(gòu)設(shè)計(jì)的適應(yīng)性更高
架構(gòu)不是一蹴而就的,在業(yè)務(wù)發(fā)展過程中,架構(gòu)也在不斷演進(jìn)
對(duì)架構(gòu)設(shè)計(jì)進(jìn)行實(shí)時(shí)調(diào)優(yōu),使架構(gòu)優(yōu)化成為常態(tài)化
通過不斷的調(diào)整架構(gòu)實(shí)現(xiàn),改進(jìn)初始架構(gòu)中設(shè)計(jì)的不足,補(bǔ)足短板
技術(shù)填補(bǔ)與崩潰預(yù)防
技術(shù)填補(bǔ)-問題1
開發(fā)過程中因?yàn)闀r(shí)間緊迫導(dǎo)致的實(shí)現(xiàn)不合理
舉例:查找10000以內(nèi)的質(zhì)數(shù)
循環(huán)的方式。帥選法
技術(shù)填補(bǔ)-問題2
暫時(shí)沒有想到更好的實(shí)現(xiàn)方式而妥協(xié)的版本
剛開始使用if…else實(shí)現(xiàn)
演變?yōu)槭褂秘?zé)任鏈模式
技術(shù)填補(bǔ)-問題3
架構(gòu)設(shè)計(jì)前期沒有考慮到的細(xì)節(jié)
交互細(xì)節(jié)->props傳遞參數(shù)(交互冗余,流程較長(zhǎng))
使用全局狀態(tài)管理實(shí)現(xiàn)參數(shù)傳遞
技術(shù)填補(bǔ)-問題4
不合理的交互設(shè)計(jì),導(dǎo)致技術(shù)實(shí)現(xiàn)復(fù)雜
技術(shù)填補(bǔ)-問題5
舊功能文檔缺失,無正確擴(kuò)展,修改和兼容舊功能,導(dǎo)致上線后問題劇增
技術(shù)填補(bǔ)-后果1
修復(fù)變重構(gòu)
小的技術(shù)債務(wù)不做償還,最后會(huì)演變成一場(chǎng)大規(guī)模的重構(gòu)工作,導(dǎo)致產(chǎn)出不高
技術(shù)填補(bǔ)-后果2
影響開發(fā)速度
技術(shù)債務(wù)的存在導(dǎo)致整體開發(fā)需要兼容的點(diǎn)過多,影響開發(fā)效率,極大影響上線速度,導(dǎo)致整體項(xiàng)目迭代緩慢,失去核心競(jìng)爭(zhēng)力
技術(shù)填補(bǔ)-后果3
容易陷入維護(hù)舊功能-開發(fā)新功能-兼容舊功能-維護(hù)舊功能-開發(fā)新功能。。。這樣的惡性循環(huán)
技術(shù)填補(bǔ)-解決方案1
優(yōu)秀的架構(gòu)設(shè)計(jì)是基礎(chǔ)
必須能夠有效處理當(dāng)前需求可預(yù)見的情況,對(duì)于未知的、可能出現(xiàn)的特殊情況,很小的改動(dòng)就能解決問題
根據(jù)當(dāng)前的業(yè)務(wù),進(jìn)行合理的項(xiàng)目拆分,盡量的代碼解耦和
必須有日志模塊,操作日志,錯(cuò)誤日志,業(yè)務(wù)日志等等
技術(shù)填補(bǔ)-解決方案2
良好的技術(shù)培訓(xùn)和傳幫帶能力
讓每一位開發(fā)者可以從更深一層次理解自己所需要實(shí)現(xiàn)的功能
從最開始的代碼規(guī)范、到熟悉業(yè)務(wù)、最好再到編寫文檔
技術(shù)填補(bǔ)-解決方案3
充分的技術(shù)方案可避免一部分技術(shù)債務(wù)的產(chǎn)生
技術(shù)方案是充分理解需求之后所能產(chǎn)出的對(duì)需求理想的實(shí)現(xiàn)方式,必要性不言而喻
技術(shù)填補(bǔ)-解決方案4
不同工程師之前可以相互review
CodeReview是非常重要的,同時(shí)也是對(duì)自身的一個(gè)提高
技術(shù)填補(bǔ)-解決方案5
提升對(duì)修復(fù)技術(shù)債務(wù)重要性的認(rèn)知
工程師如果能預(yù)見一個(gè)債務(wù)可能導(dǎo)致的問題,自然愿意花時(shí)間去處理
技術(shù)填補(bǔ)-解決方案6
善于發(fā)現(xiàn)和定期處理一些技術(shù)債務(wù)
勇于發(fā)現(xiàn)系統(tǒng)中的技術(shù)債務(wù),讓自己為系統(tǒng)負(fù)責(zé)
總結(jié)
等產(chǎn)品上線后,開發(fā)就沒有那么緊啦,這個(gè)時(shí)間大家可以找個(gè)時(shí)間處理技術(shù)債務(wù),一邊建立感情,一邊品味下原來的代碼,這種感覺極其酸爽
預(yù)防架構(gòu)崩潰
架構(gòu)崩潰是嚴(yán)重的架構(gòu)設(shè)計(jì)事故,也是我們需要預(yù)防的關(guān)鍵所在
1.系統(tǒng)崩潰的產(chǎn)生
2.日志記錄:如操作日志,錯(cuò)誤日志,業(yè)務(wù)日志等
崩潰預(yù)防
用戶行為抓去》爭(zhēng)取在最新時(shí)間獲取到用戶操作鏈條
解決存量問題〉技術(shù)債務(wù)
遏制新增》減少新增問題的概率
對(duì)臟數(shù)據(jù)進(jìn)行兜底和檢驗(yàn)
單元測(cè)試
崩潰報(bào)警
自動(dòng)化測(cè)試
更廣的灰度觸達(dá)
性能優(yōu)化體系
系統(tǒng)重構(gòu)
架構(gòu)不是永恒不變的。架構(gòu)也是具有生命周期的,也會(huì)經(jīng)歷初生、發(fā)展、巔峰、衰弱、消亡的過程
重構(gòu)是對(duì)軟件內(nèi)部結(jié)構(gòu)的一種調(diào)整,目的是在不改變軟件可觀察行為的前提下,提高其可理解性,降低其修改成本
實(shí)現(xiàn)方式:使用一系列重構(gòu)手法,在不改變軟件可觀察行為的前提下,調(diào)整其結(jié)構(gòu)
重構(gòu)理念:運(yùn)用大量微小且保持軟件行為的步驟,一步步達(dá)到大規(guī)模的修改
早期系統(tǒng)優(yōu)勢(shì)
開發(fā)速度快
代碼復(fù)雜度低
代碼規(guī)范都保持完好
嚴(yán)格注重開發(fā)規(guī)范,不會(huì)允許危及架構(gòu)設(shè)計(jì)的代碼產(chǎn)生
以上因素導(dǎo)致添加功能難度低,成本低
晚期系統(tǒng)
具備所有早期系統(tǒng)的劣勢(shì)
代碼復(fù)雜度高
代碼規(guī)范不完善
很多需求或功能出現(xiàn)逾越架構(gòu)設(shè)計(jì)的情況
添加新功能兼顧較多,涉及較多模塊,牽一發(fā)而動(dòng)全身
當(dāng)發(fā)現(xiàn)一個(gè)現(xiàn)有架構(gòu)體系已經(jīng)不能滿足當(dāng)前迭代速度的時(shí)候就需要進(jìn)行重構(gòu)工作
重構(gòu)流程
微重構(gòu)
對(duì)與壞味道的代碼通過一些重構(gòu)手段進(jìn)行微重構(gòu)
確定問題點(diǎn),確定重構(gòu)功能和范圍》舊架構(gòu)設(shè)計(jì)和邏輯梳理〉穩(wěn)定性保證》性能保證〉需求過程中的沖突問題
微前端實(shí)現(xiàn)方式對(duì)比
Iframe
優(yōu)勢(shì):
技術(shù)成熟、支持頁面嵌入、天然支持運(yùn)行沙箱隔離、獨(dú)立運(yùn)行
劣勢(shì):
頁面之間可以是不同的域名
需要對(duì)應(yīng)的設(shè)計(jì)一套應(yīng)用通訊機(jī)制,如何監(jiān)聽,傳參格式等內(nèi)容
web component
優(yōu)勢(shì):
支持自定義元素
支持shadow dom ,可通過關(guān)聯(lián)進(jìn)行控制
支持模版template和插槽slot,引入自定義組件內(nèi)容
劣勢(shì)
接入微前端需要重寫當(dāng)前項(xiàng)目
生態(tài)系統(tǒng)不完善,技術(shù)過新容易出現(xiàn)兼容性問題
整體架構(gòu)設(shè)計(jì)復(fù)雜,組件與組件之間拆分過細(xì)時(shí),容易造成通訊和控制繁瑣
自研框架
優(yōu)勢(shì)
高度定制化。滿足需要做兼容的一切場(chǎng)景
獨(dú)立的通信機(jī)制和沙箱運(yùn)行環(huán)境,可解決應(yīng)用直接相互影響的問題
支持不同技術(shù)棧子應(yīng)用,可無縫實(shí)現(xiàn)頁面無刷新渲染
劣勢(shì)
技術(shù)實(shí)現(xiàn)難度較高
需要設(shè)計(jì)一套定制的通信機(jī)制
首次加載會(huì)出現(xiàn)資源過大的情況
最終實(shí)現(xiàn)-自研框架
路由分發(fā)式
主應(yīng)用控制路由匹配和子應(yīng)用加載,共享依賴加載
子應(yīng)用做功能,并接入主應(yīng)用實(shí)現(xiàn)主子控制和聯(lián)動(dòng)
確定技術(shù)棧
應(yīng)用:主應(yīng)用、子應(yīng)用、后端服務(wù)和發(fā)布應(yīng)用
主應(yīng)用-選定vue3技術(shù)棧:vue2,vue3,react,angular,jquery,原生javascript
vue2子應(yīng)用:實(shí)現(xiàn)新能源頁面
vue3子應(yīng)用:首頁、選車
react15子應(yīng)用:資訊、視頻、視頻詳情
react16子應(yīng)用:新車、排行、登錄
服務(wù)端接口:koa實(shí)現(xiàn)
發(fā)布應(yīng)用:express
1.主應(yīng)用
注冊(cè)子應(yīng)用
加載、渲染子應(yīng)用
路由匹配(activeWhen、rules - 由框架判斷)
獲取數(shù)據(jù)(公共依賴、通過數(shù)據(jù)做鑒權(quán)處理)
通信(父子通信,子父通信)
2.子應(yīng)用的功能
渲染
監(jiān)聽通信(主應(yīng)用傳遞過來的數(shù)據(jù))
3.微前端框架
子應(yīng)用的注冊(cè)
有開始內(nèi)容(應(yīng)用加載完成,)
路由更新判斷
匹配對(duì)應(yīng)的子應(yīng)用
加載子應(yīng)用的內(nèi)容
完成所有依賴項(xiàng)的執(zhí)行
將子應(yīng)用渲染在固定容器內(nèi)
公共事件的管理
異常的捕獲和報(bào)錯(cuò)
全局的狀態(tài)管理的內(nèi)容
沙箱的隔離
通信機(jī)制
4.服務(wù)端的功能
提供數(shù)據(jù)服務(wù)
5.發(fā)布平臺(tái)
主子引用的打包和發(fā)布
總結(jié)
- 上一篇: 联想拯救者 R9000X 2023 笔记
- 下一篇: 微信接口请求问题