干凈的前端架構(gòu),圍繞這個(gè)話題有很多原則:
SOLID、KISS(保持簡(jiǎn)單明了)、DRY(不要重復(fù)自己)、DDD(領(lǐng)域驅(qū)動(dòng)設(shè)計(jì))等等。
為什么需要前端架構(gòu)?
功能性和非功能性的要求不僅應(yīng)該在后端應(yīng)用,還應(yīng)該在前端應(yīng)用。因此,有了前端架構(gòu),我們就能滿足業(yè)務(wù)需求。此外,我們能夠更好地理解項(xiàng)目的復(fù)雜性,從而降低項(xiàng)目的風(fēng)險(xiǎn)、時(shí)間和成本。然而,作者認(rèn)為,前端架構(gòu)的最有價(jià)值的原因是任何項(xiàng)目的可維護(hù)性和可擴(kuò)展性。
那么,前端架構(gòu)是什么樣的呢?
根據(jù)作者的經(jīng)驗(yàn),大多數(shù)時(shí)候都使用分層架構(gòu)。但是,也會(huì)有一些項(xiàng)目采用了六邊形架構(gòu)。
下圖簡(jiǎn)單地描繪了一個(gè)TripAgency項(xiàng)目。
使用了哪些層?
- API:由 Open-API 生成器生成的DTO和服務(wù)
- 服務(wù):包括映射器(DTO到前端模型,反之亦然)和使用 REST 端點(diǎn)與 API 通信的服務(wù)
- 存儲(chǔ):包含從服務(wù)層檢索到的所有數(shù)據(jù)
- Booking:包括模型和組件在內(nèi)的領(lǐng)域。智能組件( Smart-Components)直接與商店互動(dòng),而啞組件(Dumb components)只是可以在多個(gè)上下文中應(yīng)用的組件,因此要簡(jiǎn)單得多。
那么,這種架構(gòu)會(huì)出什么問(wèn)題呢?
那么,如果沒有定義規(guī)則,開發(fā)人員就可能直接在其組件中使用 DTO,或者在沒有存儲(chǔ)的情況下與服務(wù)層通信。或者更糟糕的是,啞組件會(huì)與服務(wù)層對(duì)話。
我們應(yīng)該如何避免這些錯(cuò)誤?
只需定義一些規(guī)則來(lái)防止這種情況發(fā)生即可。最常見的方法之一就是在項(xiàng)目中引入 Bit 或 Nx。
什么是 Bit?什么是 Nx?
Bit 和 Nx 是功能強(qiáng)大的開源構(gòu)建系統(tǒng),可提供用于提高開發(fā)人員工作效率、優(yōu)化 CI 性能和維護(hù)代碼質(zhì)量的工具和技術(shù)
因此,在使用 Bit 或 Nx 時(shí),我們可能會(huì)應(yīng)用依賴規(guī)則。因此,如果使用了錯(cuò)誤的層,開發(fā)人員就會(huì)出錯(cuò)。
我們可以將一些 DDD(域驅(qū)動(dòng)設(shè)計(jì))概念應(yīng)用到我們的 Booking 域中。因此,我們將預(yù)訂域劃分為一些子域。每個(gè)子域都有自己的邊界上下文和泛在語(yǔ)言。如下圖所示。
每個(gè)子域使用分層架構(gòu),這些子域之間的交互使用 API。功能包括智能組件和服務(wù)、用戶界面(UI)、啞組件、域模型和 Util 所有實(shí)用功能,這些功能都在此邊界上下文中使用。我們已經(jīng)很接近了,但還沒到那一步。僅有架構(gòu)是不夠的,底層組件和業(yè)務(wù)邏輯也必須使用清潔代碼原則。因此,讓我們放大功能層和用戶界面層。
哪些原則應(yīng)適用于組件?
首先是 SOLID 原則。每個(gè)組件必須只有一個(gè)責(zé)任(單一責(zé)任原則)。使用組合而非繼承(開放-封閉原則)。不要強(qiáng)迫組件實(shí)現(xiàn)不合適的接口,這意味著并非所有方法都有意義(接口隔離)。
其次,在將業(yè)務(wù)邏輯應(yīng)用到組件、服務(wù)或 Util 時(shí),不要忘記 KISS 原則。代碼要盡可能簡(jiǎn)短。為什么要這樣做呢?更簡(jiǎn)單的代碼更容易維護(hù)。
第三,盡量不要重復(fù)(DRY 原則)。將常用邏輯移至實(shí)用工具或服務(wù)中。
注:這些原則可以通過(guò)使用 Bit 輕松實(shí)現(xiàn)。在 Bit 工作區(qū)內(nèi),我們可以獨(dú)立構(gòu)建、測(cè)試、版本控制和記錄可重復(fù)使用的組件(函數(shù)、用戶界面元素或數(shù)據(jù)模型),然后將其發(fā)布到 Bit 的組件共享平臺(tái),在該平臺(tái)上,你(或其他人)可以輕松地將其導(dǎo)入到多個(gè)項(xiàng)目中。
聽起來(lái)很有道理。然而,如何才能知道哪些是應(yīng)該避免的呢?簡(jiǎn)而言之,什么是反模式?
Anti-Patterns 反模式
有一些比較常見的錯(cuò)誤?
- 導(dǎo)入不必要的庫(kù),增大捆綁包大小
- 使用嵌套訂閱
- 在模板中添加業(yè)務(wù)邏輯
- 未經(jīng)測(cè)試的業(yè)務(wù)邏輯
所以,這些都是反模式。但如何確保代碼的可維護(hù)性呢?大家可能都知道,業(yè)務(wù)邏輯會(huì)隨著時(shí)間的推移而增長(zhǎng)。簡(jiǎn)而言之,經(jīng)常會(huì)聽到以下說(shuō)法。
代碼有了歷史性的發(fā)展。起初,它是 "干凈代碼"(Clean Code),但現(xiàn)在我們的代碼已經(jīng)無(wú)法像以前那樣容易維護(hù)了。
是的,這是一個(gè)非常常見的問(wèn)題。不過(guò),以下簡(jiǎn)單的規(guī)則可以幫助我們保持可維護(hù)性。
- 定義eslint規(guī)則
- 使用stylelint
- 測(cè)試業(yè)務(wù)邏輯
- 構(gòu)建小型可重用的組件
- 使用ES6和Typescript功能
總結(jié)
本文介紹了一個(gè)簡(jiǎn)潔架構(gòu)的例子,并概述了一些可以應(yīng)用的原則。此外,還將 DDD 引入了前端架構(gòu)。最后,介紹了創(chuàng)建組件和添加業(yè)務(wù)邏輯時(shí)的一些規(guī)則,希望這些代碼能夠保持可維護(hù)性。
不過(guò),開發(fā)人員團(tuán)隊(duì)在進(jìn)行代碼審查和添加新功能時(shí)必須具備較高的標(biāo)準(zhǔn),否則清潔架構(gòu)可能不足以保持可維護(hù)性。
希望這能幫助大家構(gòu)建更簡(jiǎn)潔的前端架構(gòu)。