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