中文字幕日韩精品人妻在线视频|国产AV大学生情侣AV|99亚洲乱人伦aⅴ精品|A片一级黄片,视频,一级片网站,国产调教视频一区二区三区,26uuuuuuuuuu

×

一文讀懂架構(gòu)整潔之道

分類:互聯(lián)網(wǎng)熱點(diǎn) 編輯:新網(wǎng)小青年 瀏覽量:433
2020-07-13 16:55:23
相信大家都非常清楚,如何編寫(xiě)可讀性強(qiáng)的代碼是一個(gè)合格程序員的必修課。 我在之前的文章《談?wù)勈裁词呛玫拇a》中談了一些自己對(duì)整潔代碼的感悟,代碼并不是獨(dú)立存在的,成百上千個(gè)類的系統(tǒng)在企業(yè)應(yīng)用中非常常見(jiàn),如何將代碼進(jìn)行有效的組織,保持高可讀性,高可維護(hù)性,則是一個(gè)好的架構(gòu)需要考慮的事情。本文從原則切入,聊聊組件的分層和解耦,淺談下Bob大叔提出的整潔架構(gòu),感興趣的同學(xué)也可以發(fā)表下自己的看法。 # 原則 原則屬于做事情的指導(dǎo)方針,在討論架構(gòu)前,先來(lái)看看相關(guān)的一些原則。有適用于代碼層面的原則,有適用于再高一層級(jí)——組件的原則。 ? 代碼原則 代碼的原則有SOLID,迪米特法則,組合復(fù)用原則等等,我在談?wù)勈裁词呛玫拇a中也列出來(lái)過(guò),關(guān)于這些原則討論的文章非常之多,大家也比較熟悉,本文主要談架構(gòu)方面的,這里就不展開(kāi)了。 ? 組件原則 組件是一組代碼的集 合,拿蓋房子來(lái)打比方,代碼原則指導(dǎo)如何使用磚塊建造房間,而組件原則指導(dǎo)如何將房間構(gòu)建成高樓大廈。組件的構(gòu)建要遵循一些原則,否則即使墻砌的再好,房間修建的再漂亮,不按照規(guī)范建造,房子可能就歪歪扭扭,整棟樓房的質(zhì)量也堪憂。 組件原則包括組件內(nèi)的關(guān)系(組件聚合)以及組件間的關(guān)系(組件耦合)。 **組件聚合** 組件聚合方面的原則有以下幾個(gè): - REP:復(fù)用/發(fā)布等同原則 - CCP:共同閉包原則 - CRP:共同復(fù)用原則 REP是組件聚合總的指導(dǎo)原則,表示組件內(nèi)的類和模塊是彼此緊密相關(guān)的。CCP和CRP是對(duì)REP的補(bǔ)充,CCP可以看做是組件級(jí)別的單一職責(zé)原則(SRP):由于相同原因修改,并且需要同時(shí)修改的東西放一起;不同原因修改,并且不同時(shí)修改的東西分開(kāi)。CRP可以看做是組件級(jí)別的接口隔離原則(ISP):不要依賴不需要的東西。 可以看出通過(guò)這三個(gè)原則構(gòu)建的組件,擁有以下幾個(gè)特點(diǎn): - 組件內(nèi)的類和模塊緊密相關(guān),需求變更時(shí)通常需要同時(shí)修改; - 需求變更時(shí),需要進(jìn)行的修改只涉及很少的組件甚至在一個(gè)組件內(nèi); - 復(fù)用這個(gè)組件時(shí),通常組件內(nèi)的功能均是用戶需要的,而不是有一些不相關(guān)的功能; 這里貼下書(shū)中的張力圖: 項(xiàng)目的初期,更多關(guān)注的是維護(hù)性而犧牲復(fù)用性,隨著項(xiàng)目逐漸成熟,項(xiàng)目重心會(huì)逐漸傾向于復(fù)用性。 **組件耦合** 組件耦合方面的原則有以下幾個(gè): - ADP:無(wú)依賴環(huán)原則 - SDP:穩(wěn)定依賴原則 - SAP:穩(wěn)定抽象原則 組件間的依賴如果存在環(huán),則維護(hù)性將大大降低,我們應(yīng)該避免組件間的循環(huán)依賴。 組件間的依賴關(guān)系應(yīng)該是指向更穩(wěn)定的方向,每個(gè)組件的穩(wěn)定性 都低于其依賴的組件穩(wěn)定性。組件越穩(wěn)定,則其抽象程度需要更高;組件越不穩(wěn)定,則其抽象程度需要更低,越具體。 有時(shí)候,可能會(huì)新引入一個(gè)引用,導(dǎo)致一個(gè)穩(wěn)定的組件依賴了一個(gè)不穩(wěn)定的組件,此時(shí)就可以使用依賴倒置原則(DIP)將依賴關(guān)系反轉(zhuǎn),保持穩(wěn)定依賴。 # 分層與解耦 談了組件相關(guān)的原則,現(xiàn)在來(lái)談?wù)劷M件間的分層和隔離的方式。通過(guò)有效的分層手段,可以有效隔離不同功能的組件。 ? 水平分層 得益于MVC模式的普及,水平分層在我們的系統(tǒng)中已經(jīng)非常普及了,通常有以下幾層: 表現(xiàn)層/UI層:負(fù)責(zé)系統(tǒng)的界面展示,通常包括Controller和VO等; 領(lǐng)域?qū)?業(yè)務(wù)邏輯層:負(fù)責(zé)處理系統(tǒng)的業(yè)務(wù)邏輯,通常包括Service,Manager和DTO等; 數(shù)據(jù)層:負(fù)責(zé)與DB等底層數(shù)據(jù)存儲(chǔ)介質(zhì)通信,通常包括Mapper和DO等; ? 垂直分層 但是,僅僅做到水平分層是不夠的。當(dāng)業(yè)務(wù)邏輯比較復(fù)雜時(shí),涉及的用例會(huì)非常多,這些用例之間的變更原因幾乎肯定是不同的,所以還要進(jìn)行垂直分層,將變更原因不一樣的用例切分開(kāi)。 例如,很多系統(tǒng)的修改操作和刪除操作的變更原因和變更頻率是不一樣的,這時(shí)候可以考慮將修改和刪除進(jìn)行解耦。 不論是水平分層還是垂直分層,其核心目的都是將更新頻率不同的代碼給分開(kāi),放入不同的組件中。 ? 解耦方式 分層后的解耦方式有多種: - 源碼層次:通過(guò)控制源代碼模塊間的依賴關(guān)系進(jìn)行解耦,部署時(shí)仍然一起部署,適用于項(xiàng)目早期剛起步時(shí) - 部署層次:通過(guò)控制部署單元(例如jar包等)之間依賴進(jìn)行解耦,當(dāng)系統(tǒng)對(duì)部署和開(kāi)發(fā)方面有更高的要求時(shí),部分組件需要獨(dú)立出去形成新的部署單元; - 服務(wù)層次:通過(guò)將組件的依賴關(guān)系降低到數(shù)據(jù)結(jié)構(gòu)級(jí)別,然后通過(guò)服務(wù)進(jìn)行通信來(lái)解耦,當(dāng)系統(tǒng)足夠大的時(shí)候,就需要服務(wù)層次的解耦了; 但需要注意的是,不論通過(guò)哪種解耦方式進(jìn)行代碼的隔離,并不意味著這樣就萬(wàn)事大吉,擁有良好可擴(kuò)展和可維護(hù)性了。這也是Bob在《架構(gòu)整潔之道》中提到的“橫跨型變更”(雖然作者是在服務(wù)的這一章提出的,但我認(rèn)為也適用于其他兩種解耦層次)。 請(qǐng)看下 面的出租車調(diào)度系統(tǒng)的服務(wù)架構(gòu)圖 圖中可以看出,Taxi UI依賴 Taxi Finder查找符合條件的出租車,依賴Taxi Selector進(jìn)行出租車調(diào)度。而Taxi Finder通過(guò)多個(gè)Taxi Supplier服務(wù)獲取車輛信息,Taxi Selector依賴Taxi Dispatcher進(jìn)行最終的派單。 各個(gè)組件都是服務(wù)化的??梢钥吹?,各個(gè)組件都是具體的類,雖然各個(gè)組件隔離部署,但其實(shí)他們之間是強(qiáng)耦合的,并沒(méi)有真正的解耦:加入現(xiàn)在出租車公司準(zhǔn)備推出運(yùn)送貓咪的服務(wù),則所有的組件都需要進(jìn)行更改,同時(shí)有些同學(xué)的更改方式就是在原有的類中增加if...else,這顯然是不可取的。 正確的做法應(yīng)該是在組件最初的設(shè)計(jì)中,就應(yīng)該考慮抽象化和多態(tài),如下圖,使用策略模式或者模板方法進(jìn)行解耦: 采用面向?qū)ο蟮姆椒▉?lái)處理橫跨型變更 注意看我紅框標(biāo)出來(lái)的,除了服務(wù)間的隔離外,在組件內(nèi)部其實(shí)也存在隔離,而這個(gè)的隔離更加重要。這也就是書(shū)中講的: 服務(wù)邊界并不能代表系統(tǒng)的架構(gòu)邊界,服務(wù)內(nèi)部的組件邊界才是。 # 架構(gòu) 從代碼和組件原則到組件分層和解耦,我們逐漸對(duì)系統(tǒng)底層的一些元素有了比較深入的了解,那么上層的架構(gòu)到底是什么呢? ? 什么是架構(gòu) 并沒(méi)有非常明確的定義,這里引用書(shū)中的一些描述,大家應(yīng)該有一些體會(huì): 軟件架構(gòu)的實(shí)質(zhì)就是規(guī)劃如何將系統(tǒng)切分成組件,并安排好組件之間的排列關(guān)系,以及組件之間互相通信的方式。 軟件架構(gòu)的終極目標(biāo)是,用最小的人力成本滿足構(gòu)建和維護(hù)該系統(tǒng)的需求 需要指出的是,架構(gòu)和框架并不是相同的東西: - 架構(gòu)一定是業(yè)務(wù)相關(guān)的,包含了業(yè)務(wù)屬性,并且這個(gè)業(yè)務(wù)屬性是系統(tǒng)的核心價(jià)值; - 框架一般都是業(yè)務(wù)無(wú)關(guān)的,是我們編碼實(shí)現(xiàn)架構(gòu)的的工具,屬于實(shí)現(xiàn)細(xì)節(jié)。 最初設(shè)計(jì)系統(tǒng)架構(gòu)時(shí),并不需要過(guò)多考慮使用什么框架,而更多的是關(guān)注自身業(yè)務(wù)。 此外,很多人可能對(duì)架構(gòu)有些誤解:設(shè)計(jì)那么多有什么用,代碼不還照樣得寫(xiě)? 是的,代碼還得寫(xiě),架構(gòu)并不能讓你不寫(xiě)代碼了(有時(shí)可能還會(huì)讓你多寫(xiě)代碼)。但是,好的架構(gòu)會(huì)讓寫(xiě)代碼變得更容易了。 容易不一定是體現(xiàn)在需要變更的代碼量多少上,好的架構(gòu)可以讓你更快速的找出需要變更的范圍,并且很容易的就修改掉——這對(duì)于一個(gè)運(yùn)行維護(hù)了多年的系統(tǒng)尤為重要。大家可以回想下這樣的場(chǎng)景是不是很熟悉:明明是一個(gè)看起來(lái)很正常很合理的需求,看起來(lái)變更范圍也不大,但真的去擼代碼時(shí)發(fā)現(xiàn)需要改的地方好多,甚至無(wú)從下手去改。這個(gè)時(shí)候可能就要去看看之前的架構(gòu)設(shè)計(jì)是不是不夠合理,有哪些需要優(yōu)化改進(jìn)的。 # 六邊形架構(gòu) 六邊形架構(gòu),又名端口適配器架構(gòu)(我更喜歡這個(gè)名字,因?yàn)榱呅卫献屓烁杏X(jué)有六個(gè)什么東西跟它對(duì)應(yīng)),DDD極力推崇該架構(gòu)。系統(tǒng)的領(lǐng)域模型是系統(tǒng)最為重要的部分,而其他的諸如DB,UI,緩存,消息隊(duì)列等等均通過(guò)適配器與領(lǐng)域?qū)舆M(jìn)行通信,也就是依賴關(guān)系是由外到內(nèi)的(依賴倒置)。之前在商家規(guī)?;\(yùn)營(yíng)項(xiàng)目中也嘗試過(guò)使用DDD來(lái)進(jìn)行架構(gòu)設(shè)計(jì)。 ? 整潔架構(gòu) Bob綜合六邊形架構(gòu)和其他幾個(gè)架構(gòu)的特點(diǎn)提出了整潔架構(gòu),它具有以下幾個(gè)特點(diǎn): - 獨(dú)立于框架 - 可被測(cè)試 - 獨(dú)立于UI - 獨(dú)立于數(shù)據(jù)庫(kù) - 獨(dú)立于任何外部機(jī)構(gòu) 架構(gòu)最內(nèi)部是業(yè)務(wù)實(shí)體,代表了系統(tǒng)關(guān)鍵業(yè)務(wù)邏輯。 再外一層是用例——特定應(yīng)用場(chǎng)景下的業(yè)務(wù)邏輯,在Bob看來(lái),用例是架構(gòu)設(shè)計(jì)中非常重要的一環(huán),架構(gòu)也是基于這些用例進(jìn)行設(shè)計(jì)的,如果缺失了用例,就無(wú)從談起架構(gòu)設(shè)計(jì)了。 緊接著是控制器,網(wǎng)關(guān)和展示器,是一層接口適配器。 最外層則是框架和驅(qū)動(dòng)程序,這里面包含了數(shù)據(jù)庫(kù),web,工具等等,這一層一般只包含了一些通信的黏合性代碼。 也并不一定只有四層,真實(shí)的情況可能會(huì)超過(guò)四層,但總的原則不變:外層依賴內(nèi)存,最內(nèi)部是最通用、最高層的策略,最外層是最具體的實(shí)現(xiàn)細(xì)節(jié)。 外層的是底層組件,內(nèi)層的是高層組件,底層組件作為高層的插件存在,換句話說(shuō)外層的這個(gè)組件是可以被其他的組件像插件一樣替換掉的。 這里需要明確的一點(diǎn)是:有時(shí)候,軟件運(yùn)行的方向與依賴的方向是不同的(這個(gè)很多同學(xué)可能會(huì)沒(méi)有注意到)。比如業(yè)務(wù)實(shí)體從數(shù)據(jù)庫(kù)取數(shù)據(jù),運(yùn)行方向是業(yè)務(wù)實(shí)體->數(shù)據(jù)庫(kù),而通過(guò)依賴反轉(zhuǎn)(DI,業(yè)務(wù)實(shí)體定義查詢接口,數(shù)據(jù)庫(kù)層實(shí)現(xiàn)),我們的依賴關(guān)系是業(yè)務(wù)實(shí)體<-數(shù)據(jù)庫(kù)。這里講到的保持底層組件對(duì)高層組件的依賴,高層組件的穩(wěn)定性和抽象性,也就是前面講的SDP和SAP。 # 總結(jié) 本文從代碼和組件的原則講起,講到組件內(nèi)和組件間的關(guān)系,以及如何進(jìn)行組件的分層和隔離,接著引出了架構(gòu)相關(guān)的討論,列舉了六邊形架構(gòu)和整潔架構(gòu),并談了一些自己的理解。 后續(xù)會(huì)結(jié)合自身做過(guò)的項(xiàng)目,談一談具體的一些架構(gòu)模式。 參考: 《架構(gòu)整潔之道》 Robert C. Martin 《領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)》 Eric Evans 《企業(yè)應(yīng)用架構(gòu)模式》Martin Fowler

聲明:免責(zé)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn)自行上傳,本網(wǎng)站不擁有所有權(quán),也不承認(rèn)相關(guān)法律責(zé)任。如果您發(fā)現(xiàn)本社區(qū)中有涉嫌抄襲的內(nèi)容,請(qǐng)發(fā)

送郵件至:operations@xinnet.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),本站將立刻刪除涉嫌侵權(quán)內(nèi)容。本站原創(chuàng)內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)

需注明出處:新網(wǎng)idc知識(shí)百科

免費(fèi)咨詢獲取折扣

Loading