<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          程序員過關(guān)斬將--從未停止過的系統(tǒng)架構(gòu)設(shè)計步伐

          共 4142字,需瀏覽 9分鐘

           ·

          2020-11-21 13:39

          首先,這篇文章肯定會得罪一些人

          其次,此文只代表我個人的意見,僅供參考

          從分層說起

          談到系統(tǒng)架構(gòu)的分層和系統(tǒng)領(lǐng)域邊界的劃分,每個架構(gòu)師,每個技術(shù)經(jīng)理,甚至每個程序員都有自己的一套想法。無論是怎么樣的劃分方案,總體的目標(biāo)始終是一致的,打造一個高性能,高可用,高可擴(kuò)展,高安全性的系統(tǒng),甚至?xí)郊由弦淮蠖训膶I(yè)名詞,例如:高度一致性,可重用性,冪等性,兼容性 等等。對于最終用戶來說,無論系統(tǒng)怎么樣架構(gòu)設(shè)計,穩(wěn)定性是第一位的。假如系統(tǒng)三天兩頭打不開,報500服務(wù)器錯誤,程序員豈不是天天要被祭天?

          從很久之前的面向過程編程模式,到現(xiàn)在的面向?qū)ο笤O(shè)計,微服務(wù)架構(gòu)方案,都體現(xiàn)著架構(gòu)設(shè)計一直在追求更加極致的設(shè)計之美。而這種美要歸功于系統(tǒng)的分層設(shè)計,小到類的職責(zé)劃分,大到系統(tǒng)的分布式部署。

          系統(tǒng)為什么一定要做分層呢?至于系統(tǒng)領(lǐng)域的劃分,本質(zhì)上也是一種分層設(shè)計的體現(xiàn)思想。

          分層是軟件工程中一種常見的設(shè)計方式,它根據(jù)整個系統(tǒng)的職責(zé)鏈把系統(tǒng)邏輯上拆分為多個層,每個層都有相對明確的獨立的職責(zé),多個層通過協(xié)調(diào)提供完整的功能。至于每層負(fù)責(zé)什么職責(zé),軟件工程學(xué)并沒有明確的定義,系統(tǒng)的設(shè)計者可以根據(jù)系統(tǒng)特點來具體劃分,比如:最常見的三層架構(gòu)設(shè)計,把整個系統(tǒng)劃分為:

          • UI層,主要負(fù)責(zé)用戶UI的職責(zé)
          • 業(yè)務(wù)層,主要負(fù)責(zé)業(yè)務(wù)邏輯相關(guān)職責(zé)
          • 數(shù)據(jù)持久化層,主要負(fù)責(zé)數(shù)據(jù)的持久化,落盤操作
          image

          還有我們耳熟能詳?shù)腛SI網(wǎng)絡(luò)模型,它把整個網(wǎng)絡(luò)劃分為了七層,每層都有相對明確的職責(zé),但是還有另外一種劃分方式把網(wǎng)絡(luò)模型劃分為四層,這是根據(jù)不同職責(zé)來劃分網(wǎng)絡(luò)的典型案例。

          軟件設(shè)計采用分層設(shè)計算是一種工程學(xué),它把整體系統(tǒng)劃分為不同的層,之后采用不同的依賴方式來組織功能,帶來了很多優(yōu)勢

          • 每層的職責(zé)明確,而且依賴關(guān)系明確
          • 每層都可以復(fù)用,減少了代碼重復(fù)率
          • 每層都可以相對獨立的做修改,擴(kuò)展等,不會影響其他層

          看到不少技術(shù)經(jīng)理乃至架構(gòu)師一直鄙視使用三層架構(gòu)的程序員,我覺得你需要反思一下。最簡單的三層架構(gòu)模式并非優(yōu)勢全無,據(jù)我所知,在快速應(yīng)對中小系統(tǒng)開發(fā)的時候,三層架構(gòu)仍然是首選。不要整天拿著所謂的DDD說事,DDD也不是銀彈,簡單的三層架構(gòu),甚至貧血模型開發(fā)模式也有自己的優(yōu)勢,更何況一些人高舉DDD的“聚合根”,“值類型”等概念,其實并未真正理解其含義和設(shè)計理念,自以為看了幾篇DDD的文章,就可以妄自吹噓自己精通DDD,領(lǐng)域模型開發(fā)確實是好的開發(fā)理念,但是它也有自己的劣勢,不是任何系統(tǒng)用DDD開發(fā)都是最優(yōu)的,更何況那些沒有實際DDD開發(fā)經(jīng)驗的“高層”。

          系統(tǒng)拆分

          雖然分層設(shè)計優(yōu)勢很明顯,但是隨著系統(tǒng)業(yè)務(wù)越來越復(fù)雜,就面臨著層次劃分越來越多的窘態(tài)。這也是系統(tǒng)發(fā)展的一個必然結(jié)果,也是單體應(yīng)用的必然瓶頸。所以系統(tǒng)按照業(yè)務(wù)拆分是業(yè)務(wù)發(fā)展到一定階段的結(jié)果,而并非架構(gòu)師主觀意愿的結(jié)果。隨著子系統(tǒng)越來越多,部署和運維工作也隨著越來越多,所以自動化的部署需求也隨之出現(xiàn),為了更好的實現(xiàn)每個系統(tǒng)的可擴(kuò)展性,穩(wěn)定性,可用性等軟性需求,kubernetes也越來越受到追捧。

          其實系統(tǒng)拆分是一個很泛的概念,業(yè)界并沒有實際的拆分原則,只是大部分人喜歡以業(yè)務(wù)為維度來進(jìn)行拆分,實際證明按照業(yè)務(wù)拆分也是正確的。被拆分的不止是業(yè)務(wù)邏輯的代碼,包括業(yè)務(wù)的數(shù)據(jù)庫等也會被徹底物理隔離,因為只有這樣才可以做到真正的高內(nèi)聚,低耦合。

          image

          架構(gòu)設(shè)計

          當(dāng)每個服務(wù)都可以根據(jù)自身業(yè)務(wù)量來進(jìn)行橫向擴(kuò)展或者縱向擴(kuò)展的時候,就可以體現(xiàn)出微服務(wù)的優(yōu)勢。而具體的系統(tǒng)架構(gòu)設(shè)計決定著這個服務(wù)是否可以靈活的應(yīng)對多變的業(yè)務(wù)需求,說到底,我們又回到怎樣設(shè)計單體系統(tǒng)的話題上來了。其實設(shè)計好單體架構(gòu)并不比分布式系統(tǒng)容易,一個好的單體系統(tǒng)同樣也需要設(shè)計模式,數(shù)據(jù)結(jié)構(gòu),算法和抽象。前面所說的三層架構(gòu)是其中一種選擇。

          系統(tǒng)的設(shè)計離不開業(yè)務(wù),任何脫離業(yè)務(wù)的系統(tǒng)架構(gòu)設(shè)計都是耍流氓。設(shè)計一個靈活的系統(tǒng)需要對業(yè)務(wù)的變化點進(jìn)行正確的識別,然后進(jìn)行抽象,比如:注冊新用戶的時候,需要給用戶發(fā)送短信歡迎語,其實這是一個業(yè)務(wù)的變化點,因為產(chǎn)品不知道哪天會有一個發(fā)送郵件的歡迎語,甚至如果關(guān)注了公眾號,會發(fā)送公眾號消息。

          三層架構(gòu)在應(yīng)對大型系統(tǒng)的時候之所以力不從心,是因為他并不是按照業(yè)務(wù)的對象進(jìn)行分層抽象,而現(xiàn)在流行的DDD更加貼近現(xiàn)實世界中的抽象層次,所以DDD在大型系統(tǒng)中更加游刃有余。其中有一種六邊形的架構(gòu)理論值得我們學(xué)習(xí)。

          六邊形架構(gòu)設(shè)計

          image

          六邊形架構(gòu)設(shè)計本質(zhì)上還是一種分層架構(gòu)設(shè)計方案,但是它不同于傳統(tǒng)的三層架構(gòu),傳統(tǒng)的三層架構(gòu)自上而下逐層依賴,而六邊形架構(gòu)設(shè)計采用了內(nèi)部外部的分層思想,它把業(yè)務(wù)的領(lǐng)域模型最為最核心的概念,然后擴(kuò)展出外層的應(yīng)用層,其實領(lǐng)域模型和應(yīng)用層就是系統(tǒng)的業(yè)務(wù)層。

          內(nèi)部通過端口和外部系統(tǒng)通信,端口代表了一定協(xié)議,以API呈現(xiàn)。一個端口可能對應(yīng)多個外部系統(tǒng),不同的外部系統(tǒng)需要使用不同的適配器,適配器負(fù)責(zé)對協(xié)議進(jìn)行轉(zhuǎn)換。這樣就使得應(yīng)用程序能夠以一致的方式被用戶、程序、自動化測試、批處理腳本所驅(qū)動,并且,可以在與實際運行的設(shè)備和數(shù)據(jù)庫相隔離的情況下開發(fā)和測試。

          • 領(lǐng)域?qū)樱侯I(lǐng)域?qū)邮菢I(yè)務(wù)最核心的概念,包括領(lǐng)域?qū)ο蟮臓顟B(tài),規(guī)則,行為等。
          • 應(yīng)用層:定義了系統(tǒng)可以完成的功能,它通過協(xié)調(diào)多個領(lǐng)域?qū)ο髞硗瓿蓸I(yè)務(wù)邏輯,這一層會包含事務(wù)的管理。
          • 輸入端口:用于接收外部系統(tǒng)的輸入,可以認(rèn)為它是暴露在外邊的接口
          • 輸出端口:為系統(tǒng)獲取外部服務(wù)提供支持,如獲取持久化狀態(tài)、對結(jié)果進(jìn)行持久化,或者發(fā)布領(lǐng)域狀態(tài)的變更通知(如領(lǐng)域事件)。系統(tǒng)作為服務(wù)的消費者獲取服務(wù)是對外的接口(數(shù)據(jù)庫、緩存、消息隊列、RPC調(diào)用)等都可以看成是輸入端口。

          六邊形理論從一開始就強(qiáng)調(diào)把中心放在業(yè)務(wù)邏輯上,外部的端口存在可變性,可替換性,這是依賴倒置規(guī)則的體現(xiàn)。下面就以用戶注冊業(yè)務(wù)來模擬一下

          首先為核心的用戶領(lǐng)域模型,以及模型的行為,其中持久化數(shù)據(jù)的行為依賴于接口

          //用戶領(lǐng)域?qū)ο?br>????public?class?UserDomain
          ????{
          ????????public?int?UserId?{?get;?set;??}

          ????????public?string?UserName?{?get;?set;?}

          ????????//注冊新用戶行為
          ????????public?int?UpdateName(string?name)
          ????????{
          ????????????
          ????????????IUserDomainRepositoryAdpater?resAdapter?=?ioc方式獲取注入的實例/或者其他渠道;

          ????????????return?resAdapter.UpdateUserName(this.UserId,name);
          ????????}
          ????}

          然后是用戶的應(yīng)用,其中給用戶發(fā)送歡迎語的行為依賴于接口

          ?public?class?UserApplication
          ????{
          ????????public?int?UpdateuserName(int?userId,string?name)
          ????????{
          ????????????UserDomain?user?=?new?UserDomain()?{?UserId?=?userId,?UserName?=?name?};
          ????????????user.UpdateName("新用戶名");

          ????????????ISendMessageAdpater?sendMessage?=?ioc獲取實例;
          ????????????sendMessage.SendMessage(userId.ToString(),"新用戶注冊");


          ????????}
          ????}
          ?????//發(fā)送消息的適配器
          ????public?interface?ISendMessageAdpater
          ????{
          ????????//給用戶發(fā)送消息
          ????????void?SendMessage(string?user,string?content);
          ????}

          到此為止,用戶核心業(yè)務(wù)已經(jīng)編寫完畢,可以看到,其中業(yè)務(wù)的變化點都是依賴于接口,對應(yīng)到六邊形理論中,對應(yīng)的就是各種adapter,接下來只要把各種適配器實現(xiàn),然后注入(安裝)到系統(tǒng),整個系統(tǒng)就可以運行起來了。

          //外部的adapter的實現(xiàn)
          ????public?class?UserDomainRepositoryAdpater:?IUserDomainRepositoryAdpater
          ????{
          ????????public?int?UpdateUserName(int?userId,?string?name)
          ????????{
          ????????????//具體的sql執(zhí)行過程
          ????????}
          ????}
          public?class?SendEmailAdpater:?ISendMessageAdpater
          ????{
          ????????//給用戶發(fā)送郵件
          ????????public?void?SendMessage(string?user,?string?content)
          ????????{

          ????????}
          ????}

          ????public?class?SendPhoneCodeAdpater?:?ISendMessageAdpater
          ????{
          ????????//給用戶發(fā)送短信
          ????????public?void?SendMessage(string?user,?string?content)
          ????????{

          ????????}
          ????}

          不難看出,六邊形理論其實是抽象業(yè)務(wù)模型+面型接口編程的有效組合,當(dāng)然真正的項目中還有可能涉及到很多設(shè)計模式相關(guān)的設(shè)計理念。對應(yīng)到平時開發(fā)中,mvc的controller層已然變成六邊形的輸入adapter的一種,它負(fù)責(zé)請求業(yè)務(wù)提供的接口來實現(xiàn)系統(tǒng)業(yè)務(wù)。

          瀏覽 43
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  AV55 | 免费高清AV在线看 | 久久无码视频电影 | 狠狠2022 | 伊人亚洲 | 欧美A级黄色网址 |